why chained IObservables invoke functions called by the previous IObservable - c#

public static void Main(string[] args)
{
var inputs = new Subject<string>();
IObservable<decimal> rates =
from pair in inputs
from rate in RatesApi.GetRateAsync(pair)
select rate;
IObservable<string> outputs = from r in rates select r.ToString(); // <------line a
using (inputs.Trace("inputs"))
using (rates.Trace("rates"))
using (outputs.Trace("outputs")) // <---------------------------------------line b
for (string input; (input = Console.ReadLine().ToUpper()) != "Q";)
inputs.OnNext(input);
}
public static IDisposable Trace<T>(this IObservable<T> source, string name)
{
return source.Subscribe
(
onNext: t => Console.WriteLine($"{name} -> {t}"),
onError: ex => Console.WriteLine($"{name} ERROR: {ex.Message}"),
onCompleted: () => Console.WriteLine($"{name} END")
);
}
public static async Task<decimal> GetRateAsync(string ccyPair)
{
Console.WriteLine($"fetching rate...");
... // api to fetch exchange rate
}
when I ran the program, I found "fetching rate..." is printed twice, which I thought it should only print once. Then I found if I remove line a and line b, then the program only prints "fetching rate..." once.
But why this line of code IObservable<string> outputs = from r in rates select r.ToString(); cause the program to print "fetching rate..." string one more time?
I still think "fetching rate..." should only printed once for the code below only:
IObservable<decimal> rates =
from pair in inputs
from rate in RatesApi.GetRateAsync(pair)
select rate;

Why are you using IObservable for this at all, could you just use a List
List<decimal> rates =
(from pair in inputs
from rate in RatesApi.GetRateAsync(pair)
select rate).ToList();
You should also move rates out of the Main method if you intend to reuse the result.
To answer your question it printed like that because you called GetRateAsync(pair) twice, This happened because you aren't storing the result of the query.

Related

c# Write more item from the list not one

public static void work_3()
{
Console.WriteLine("3_work");
int chosenday = Convert.ToInt32(Console.ReadLine());
Cardatas cdat = Cardata.Find(x => x.Day.Equals(chosenday));
Console.WriteLine($"The traffic at {chosenday}: {cdat.time.ToShortTimeString()} {cdat.licenseplate}");
}
I have a data list about car datas
2 19:32 CEG305 574 8912 1
2 19:35 CEG304 578 8932 1
like this, and I managed to write out the information what I wanted to but It just write one data of the many.
private static List<Cardatas> Cardata= new List<Cardatas>();
Use the Linq extension Where instead of Find to get all the matching elements, then loop on the result enumerable:
IEnumerable<Cardatas> allCdats = Cardata.Where(x => x.Day.Equals(chosenday));
foreach (Cardatas cdat in allCdats)
{
Console.WriteLine($"The traffic at {chosenday}: cdat.time.ToShortTimeString()} {cdat.licenseplate}");
}
Note: you'll need using System.Linq and using System.Collections.Generics for the above code.

C# Comparing an Input to a String Exactly

I have a list of most of the elements in the periodic table in order of their placement on the table:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Chemistry_Element_Calculator
{
class Program
{
static void Main(string[] args)
{
// Declare all numbers
int electronNumber;
int protonNumber;
float neutronNumber;
int i;
// Declare all strings
string elementRequest;
// Create an list for all elements
List<string> elementNameList = new List<string>();
List<string> elementSymbolList = new List<string>();
// Add all elements to the list
elementNameList.Add("Hydrogen"); elementSymbolList.Add("H");
elementNameList.Add("Helium"); elementSymbolList.Add("He");
elementNameList.Add("Lithium"); elementSymbolList.Add("Li");
elementNameList.Add("Beryllium"); elementSymbolList.Add("Be");
elementNameList.Add("Boron"); elementSymbolList.Add("B");
elementNameList.Add("Carbon"); elementSymbolList.Add("C");
elementNameList.Add("Nitrogen"); elementSymbolList.Add("N");
elementNameList.Add("Oxygen"); elementSymbolList.Add("O");
elementNameList.Add("Fluorine"); elementSymbolList.Add("F");
elementNameList.Add("Neon"); elementSymbolList.Add("Ne");
elementNameList.Add("Sodium"); elementSymbolList.Add("Na");
elementNameList.Add("Magnesium"); elementSymbolList.Add("Mg");
elementNameList.Add("Aluminium"); elementSymbolList.Add("Al");
elementNameList.Add("Silicon"); elementSymbolList.Add("Si");
elementNameList.Add("Phosphorus"); elementSymbolList.Add("P");
elementNameList.Add("Sulfur"); elementSymbolList.Add("S");
elementNameList.Add("Chlorine"); elementSymbolList.Add("Cl");
elementNameList.Add("Argon"); elementSymbolList.Add("Ar");
elementNameList.Add("Potassium"); elementSymbolList.Add("K");
elementNameList.Add("Calcium"); elementSymbolList.Add("Ca");
elementNameList.Add("Scandium"); elementSymbolList.Add("Sc");
elementNameList.Add("Titanium"); elementSymbolList.Add("Ti");
elementNameList.Add("Vanadium"); elementSymbolList.Add("V");
elementNameList.Add("Chromium"); elementSymbolList.Add("Cr");
elementNameList.Add("Manganese"); elementSymbolList.Add("Mn");
elementNameList.Add("Iron"); elementSymbolList.Add("Fe");
elementNameList.Add("Cobalt"); elementSymbolList.Add("Co");
elementNameList.Add("Nickel"); elementSymbolList.Add("Ni");
elementNameList.Add("Copper"); elementSymbolList.Add("Cu");
elementNameList.Add("Zinc"); elementSymbolList.Add("Zn");
elementNameList.Add("Gallium"); elementSymbolList.Add("Ga");
elementNameList.Add("Germanium"); elementSymbolList.Add("Ge");
elementNameList.Add("Arsenic"); elementSymbolList.Add("As");
elementNameList.Add("Selenium"); elementSymbolList.Add("Se");
elementNameList.Add("Bromine"); elementSymbolList.Add("Br");
elementNameList.Add("Krypton"); elementSymbolList.Add("Kr");
elementNameList.Add("Rubidium"); elementSymbolList.Add("Rb");
elementNameList.Add("Strontium"); elementSymbolList.Add("Sr");
elementNameList.Add("Yttrium"); elementSymbolList.Add("Y");
elementNameList.Add("Zirconium"); elementSymbolList.Add("Zr");
elementNameList.Add("Niobium"); elementSymbolList.Add("Nb");
elementNameList.Add("Molybdenum"); elementSymbolList.Add("Mo");
elementNameList.Add("Technetium"); elementSymbolList.Add("Tc");
elementNameList.Add("Rubidium"); elementSymbolList.Add("Ru");
elementNameList.Add("Rhodium"); elementSymbolList.Add("Rh");
elementNameList.Add("Palladium"); elementSymbolList.Add("Pd");
elementNameList.Add("Silver"); elementSymbolList.Add("Ag");
elementNameList.Add("Cadmium"); elementSymbolList.Add("Cd");
elementNameList.Add("Indium"); elementSymbolList.Add("In");
elementNameList.Add("Tin"); elementSymbolList.Add("Sn");
elementNameList.Add("Antimony"); elementSymbolList.Add("Sb");
elementNameList.Add("Tellurium"); elementSymbolList.Add("Te");
elementNameList.Add("Iodine"); elementSymbolList.Add("I");
elementNameList.Add("Xenon"); elementSymbolList.Add("Xe");
elementNameList.Add("Caesium"); elementSymbolList.Add("Cs");
elementNameList.Add("Barium"); elementSymbolList.Add("Ba");
elementNameList.Add("Lanthanum"); elementSymbolList.Add("La");
elementNameList.Add("Cerium"); elementSymbolList.Add("Ce");
elementNameList.Add("Praseodynium"); elementSymbolList.Add("Pr");
elementNameList.Add("Neodymium"); elementSymbolList.Add("Nd");
elementNameList.Add("Promethium"); elementSymbolList.Add("Pm");
elementNameList.Add("Samarium"); elementSymbolList.Add("Sm");
elementNameList.Add("Europium"); elementSymbolList.Add("Eu");
elementNameList.Add("Gadolinium"); elementSymbolList.Add("Gd");
elementNameList.Add("Terbium"); elementSymbolList.Add("Tb");
elementNameList.Add("Dysprosium"); elementSymbolList.Add("Dy");
elementNameList.Add("Holomium"); elementSymbolList.Add("Ho");
elementNameList.Add("Erbium"); elementSymbolList.Add("Er");
elementNameList.Add("Thulium"); elementSymbolList.Add("Tm");
elementNameList.Add("Ytterbium"); elementSymbolList.Add("Yb");
elementNameList.Add("Lutenium"); elementSymbolList.Add("Lu");
elementNameList.Add("Hafnium"); elementSymbolList.Add("Hf");
elementNameList.Add("Tantalum"); elementSymbolList.Add("Ta");
elementNameList.Add("Tungsten"); elementSymbolList.Add("W");
elementNameList.Add("Rhenium"); elementSymbolList.Add("Re");
elementNameList.Add("Osmium"); elementSymbolList.Add("Os");
elementNameList.Add("Iridium"); elementSymbolList.Add("Ir");
elementNameList.Add("Platinum"); elementSymbolList.Add("Pt");
elementNameList.Add("Gold"); elementSymbolList.Add("Au");
elementNameList.Add("Mercury"); elementSymbolList.Add("Hg");
elementNameList.Add("Thallium"); elementSymbolList.Add("Tl");
elementNameList.Add("Lead"); elementSymbolList.Add("Pb");
elementNameList.Add("Bismuth"); elementSymbolList.Add("Bi");
elementNameList.Add("Polonium"); elementSymbolList.Add("Po");
elementNameList.Add("Astatine"); elementSymbolList.Add("At");
elementNameList.Add("Radon"); elementSymbolList.Add("Rn");
elementNameList.Add("Francium"); elementSymbolList.Add("Fr");
elementNameList.Add("Radium"); elementSymbolList.Add("Ra");
elementNameList.Add("Actinium"); elementSymbolList.Add("Ac");
elementNameList.Add("Thorium"); elementSymbolList.Add("Th");
elementNameList.Add("Palladium"); elementSymbolList.Add("Pa");
elementNameList.Add("Uranium"); elementSymbolList.Add("U");
elementNameList.Add("Nepturium"); elementSymbolList.Add("Np");
elementNameList.Add("Plutonium"); elementSymbolList.Add("Pu");
elementNameList.Add("Americium"); elementSymbolList.Add("Am");
elementNameList.Add("Curium"); elementSymbolList.Add("Cm");
elementNameList.Add("Berkelium"); elementSymbolList.Add("Bk");
elementNameList.Add("Californium"); elementSymbolList.Add("Cf");
elementNameList.Add("Einsteinium"); elementSymbolList.Add("Es");
elementNameList.Add("Fermium"); elementSymbolList.Add("Fermium");
elementNameList.Add("Mendelevium"); elementSymbolList.Add("Md");
elementNameList.Add("Nobelium"); elementSymbolList.Add("No");
elementNameList.Add("Lawrencium"); elementSymbolList.Add("Lr");
elementNameList.Add("Rutherfordium"); elementSymbolList.Add("Rf");
elementNameList.Add("Dubnium"); elementSymbolList.Add("Db");
elementNameList.Add("Seaborgium"); elementSymbolList.Add("Sg");
elementNameList.Add("Bohrium"); elementSymbolList.Add("Bh");
elementNameList.Add("Hassium"); elementSymbolList.Add("Hs");
elementNameList.Add("Meitnerium"); elementSymbolList.Add("Mt");
elementNameList.Add("Darmstadtium"); elementSymbolList.Add("Ds");
elementNameList.Add("Roentgenium"); elementSymbolList.Add("Rg");
elementNameList.Add("Copernicium"); elementSymbolList.Add("Cn");
Console.WriteLine("What element do you want? Either input it's full name, with a capital letter, or it's elemnent symbol. E.g. N for Nitrogen");
elementRequest = Console.ReadLine();
elementNameList.ForEach(delegate (String elementName)
{
if (elementRequest == elementName)
{
Console.WriteLine("Hydrogen");
}
else
{
Console.WriteLine("Not Hydrogen");
};
});
Console.Read();
However, when I run the program, and input Hydrogen, both Helium and Hydrogen are said to be hydrogen. How can I fix this?
Also, if anyone has an idea on how to compress the 2 lists so they're smaller, let me know :)
Thanks :)
What you want your code to do is take the index from the first list, and return the string at the same index in the second list.
Your code is currently not doing any of that, but always printing "Hydrogen", your output thus always being "Hydrogen" whatever element is requested.
You can trivially fix that by actually looking up the index:
int indexOfElementName = elementNameList.IndexOf(elementRequest);
string elementSymbol = elementSymbolList[indexOfElementName];
Note that that does not handle casing and requested elements that aren't in the list (or typos).
But keeping the two lists in sync, and this code in general, is a maintenance disaster waiting to happen.
Instead you could use a dictionary where the element name is the key and the symbol the value:
var elementDictionary = new Dictionary<string, string>
{
{ "Hydrogen", "H" },
{ "Helium", "He" },
// ...
}
Then look it up:
string elementSymbol = elementDictionary[elementRequest];
Do note that this still doesn't handle case-insensitivity and elements that are not found, but I'll leave that as an exercise to you.
I would use a custom class and a list as suggested by ElectricRouge.
I don't favor the dictionary because you need to search both by name and symbol. Also, the data set is small (118 elements to date).
See comments for the explanation of the code.
using System;
using System.Collections.Generic;
namespace Chemistry_Element_Calculator
{
// Create a chemical element class
// You can add more properties such as number of electrons, etc.
public class ChemicalElement
{
public string Symbol
{
get; set;
}
public string Name
{
get; set;
}
}
class Program
{
static void Main(string[] args)
{
// Create a list of the elements, populate their properties
var elements = new List<ChemicalElement>()
{
new ChemicalElement {Name = "Hydrogen", Symbol = "H"},
new ChemicalElement {Name = "Helium", Symbol = "He"},
new ChemicalElement {Name = "Lithium", Symbol = "Li"}
// etc.
};
Console.WriteLine("What element do you want? Either input it's full name, with a capital letter, or it's elemnent symbol. E.g. N for Nitrogen");
var elementRequest = Console.ReadLine();
// Use find to get a matching element, compare both name and symbol
var foundElement = elements.Find(element => element.Symbol == elementRequest || element.Name == elementRequest);
if (foundElement == null)
{
// Output if no element is found
Console.WriteLine("Element Not Found");
}
else
{
// Output if the element is found
Console.WriteLine("Found element {0}.", foundElement.Name);
}
Console.WriteLine("[Press any key to finish]");
Console.ReadKey();
}
}
}
The code uses the method List.Find to get the result, it will only return the first match.
I would also suggest to migrate to String.Compare if you want to have case-insensitive comparison.
And finally I would be reading the data form file or a database, but that is beyond the question.

Streaming an IConnectableObservable after processing

I am trying to write a method that takes an IConnectableObservable, does some processing on it and returns a new IConnectableObservable that streams the processed data plus some additional items. The sequence being streamed is finite, but it has side effects so it needs to be run only once. However, I am trying to do two things with it:
Transform each element in the stream using a Select query.
Collect each element in the stream into an array and do some processing on the array and stream the results.
Below is my best attempt at doing this, but I feel that there probably is a superior way of doing this that I haven't figured out.
protected override IConnectableObservable<ITestResult<ITestOutput<double, double>, ITestLimit<double>>> ProcessOutput(
IConnectableObservable<ITestOutput<double, double>> output, InputVerificationTestCase testCase)
{
var obsResults = output.Select(o =>
{
var limits = GenerateDcAccuracyLimits.CalculateAbsoluteLimits(o.Input, testCase.FullScaleRange, testCase.Limits);
return new TestResult<ITestOutput<double, double>, ITestLimit<double>>
{
Component = "Variable Gain Module Input",
Description = "Measurement Accuracy",
Limits = limits,
Output = o,
Passed = _validationService.Validate(o.Result, limits)
};
});
var observable = Observable.Create<ITestResult<ITestOutput<double, double>, ITestLimit<double>>>(obs =>
{
var resultTask = obsResults.ForEachAsync(obs.OnNext);
var fitTask = output.ToArray().ForEachAsync(arr =>
{
resultTask.Wait();
var fit = ComputeErrorFit(arr, testCase);
obs.OnNext(GetGainErrorResult(fit.Item2, testCase));
});
output.Connect();
Task.WaitAll(resultTask, fitTask);
obs.OnCompleted();
return Disposable.Empty;
});
return observable.Publish();
}
Edited 10/7/2015:
Here is the rest of the code:
private ITestResult<ITestOutput<double, double>, ITestLimit<double>> GetGainErrorResult(double gainError, InputVerificationTestCase testCase)
{
var gainErrorLimit = GenerateDcAccuracyLimits.CalculateGainErrorLimits(testCase.FullScaleRange, testCase.Limits);
return new TestResult<ITestOutput<double, double>, ITestLimit<double>>
{
Component = "Variable Gain Module Input",
Description = "Gain Error",
Passed = _validationService.Validate(gainError, gainErrorLimit),
Output = new TestOutput<double, double> { Input = 0, Result = gainError },
Limits = gainErrorLimit
};
}
private Tuple<double, double> ComputeErrorFit(ITestOutput<double, double>[] outputs, InputChannelTestCase testCase)
{
var input = outputs.Select(o => o.Input);
var vErr = outputs.Select(o => o.Result - o.Input);
return Fit.Line(input.ToArray(), vErr.ToArray());
}
Also in an abstract base class, I have the following:
public IConnectableObservable<TOutput> RunSingleChannel(TCase testCase)
{
dut.Acquisition.SampleRate.Value = SampleRate;
dut.AnalogChannels[testCase.Channel].InputRange.Value = testCase.FullScaleRange;
var testOutput = CreateTestProcedure(testCase.Channel).RunAsync(testCase.InputVoltages);
return ProcessOutput(testOutput.Replay(), testCase);
}
protected abstract IConnectableObservable<TOutput> ProcessOutput(IConnectableObservable<ITestOutput<double, TAcq>> output, TCase testCase);
It seems that you're going about doing things the hard way with Rx. You really need to avoid mixing in Tasks with Observables. They make your code hard to reason about and often lead to deadlocks and other concurrency issues.
You should try something like this instead:
protected override IConnectableObservable<ITestResult<ITestOutput<double, double>, ITestLimit<double>>> ProcessOutput(
IConnectableObservable<ITestOutput<double, double>> output, InputVerificationTestCase testCase)
{
var source = output.RefCount();
return
source
.Select(o =>
{
var limits = GenerateDcAccuracyLimits.CalculateAbsoluteLimits(o.Input, testCase.FullScaleRange, testCase.Limits);
return new TestResult<ITestOutput<double, double>, ITestLimit<double>>
{
Component = "Variable Gain Module Input",
Description = "Measurement Accuracy",
Limits = limits,
Output = o,
Passed = _validationService.Validate(o.Result, limits)
};
})
.Merge(
source
.ToArray()
.Select(arr => GetGainErrorResult(ComputeErrorFit(arr, testCase).Item2, testCase)))
.Publish();
}
It's a little odd that you're using connectable observables, but the above should roughly be doing what you need.
I've tested the code using this sample:
public IConnectableObservable<int> ProcessOutput(IConnectableObservable<int> output)
{
var source = output.RefCount();
return
source
.Merge(source.ToArray().Select(arr => arr.Sum()))
.Publish();
}
void Main()
{
var output = Observable.Range(1, 10).Publish();
var processed = ProcessOutput(output);
processed.Subscribe(x => Console.WriteLine(x));
processed.Connect();
}
Which outputs:
1
2
3
4
5
6
7
8
9
10
55
I've also checked that the original observable values are only produced once.

c# linq list with varying where conditions

private void getOrders()
{
try
{
//headerFileReader is assigned with a CSV file (not shown here).
while (!headerFileReader.EndOfStream)
{
headerRow = headerFileReader.ReadLine();
getOrderItems(headerRow.Substring(0,8))
}
}
}
private void getOrderItems(string ordNum)
{
// lines is an array assigned with a CSV file...not shown here.
var sorted = lines.Skip(1).Select(line =>
new
{
SortKey = (line.Split(delimiter)[1]),
Line = line
})
.OrderBy(x => x.SortKey)
.Where(x => x.SortKey == ordNum);
//Note ordNum is different every time when it is passed.
foreach (var orderItems in sorted) {
//Process each line here.
}
}
Above is my code. What I am doing is for every order number from headerFile, I process the detailLines. I would like to only search for those lines specific to the order nr. The above logic works fine but it reads with where clause for every order number which simply is not required as well as delays the process.
I basically want to have getOrderItems something like below but I can't get as the sorted can't be passed but I think it should be possible??
private void getOrderItems(string ordNum)
{
// I would like to have sorted uploaded with data elsewhere and I pass it this function and reference it by other means but I am not able to get it.
var newSorted = sorted.Where(x => x.SortKey == docNum);
foreach (var orderItems in newSorted) {
//Process each line here.
}
}
Please suggest.
UPDATE : Thanks for the responses & improvements but my main question is I don't want to create the list every time (like I have shown in my code). What I want is to create the list first time and then only search within the list for a particular value (here docNum as shown). Please suggest.
It might be a good idea to preprocess your input lines and build a dictionary, where each distinct sort key maps to a list of lines. Building the dictionary is O(n), and after that you get constant time O(1) lookups:
// these are your unprocessed file lines
private string[] lines;
// this dictionary will map each `string` key to a `List<string>`
private Dictionary<string, List<string>> groupedLines;
// this is the method where you are loading your files (you didn't include it)
void PreprocessInputData()
{
// you already have this part somewhere
lines = LoadLinesFromCsv();
// after loading, group the lines by `line.Split(delimiter)[1]`
groupedLines = lines
.Skip(1)
.GroupBy(line => line.Split(delimiter)[1])
.ToDictionary(x => x.Key, x => x.ToList());
}
private void ProcessOrders()
{
while (!headerFileReader.EndOfStream)
{
var headerRow = headerFileReader.ReadLine();
List<string> itemsToProcess = null;
if (groupedLines.TryGetValue(headerRow, out itemsToProcess))
{
// if you are here, then
// itemsToProcess contains all lines where
// (line.Split(delimiter)[1]) == headerRow
}
else
{
// no such key in the dictionary
}
}
}
The following will get your way and also be more efficient.
var sorted = lines.Skip(1)
.Where(line => (line.Split(delimiter)[1] == ordNum))
.Select(
line =>
new
{
SortKey = (line.Split(delimiter)[1]),
Line = line
}
)
.OrderBy(x => x.SortKey);

Abort ado.net query

I am implementing a autocomplete control. Every time the user types a new character into a input, a query will fire. In order to test I have created a large database where the average query takes about 5 seconds to execute.
Because the query takes 5 seconds to execute I execute the query on a new thread:
// execute the following lamda expression when user enters characters to textbox
textBox1.TextChanged +=(x,eventArgs)=>{
// execute query on separate thread
new Thread(new ThreadStart(() =>
{
ObservableCollection = MyEntities.Entities.Products.Where(p => p.Name.Contains(inputText));
})).Start();
};
ObservableCollection and inputText are properties binded to my textbox and list.
The problem is that if the user types two characters my program will be running two threads at the same time. How can I abort the query?
Things that I am thinking about:
Create a bool variable IsQueryRuning and set it equal to true quen query starts and equal to false when thread ends. If a new query will be executed and IsQueryRuning = true then I can set ObservableCollection =null and cause an exeption. I will then resove it with a try catch block. I think that technique is not the best approach..
Edit:
Setting property Collection=null sometimes causes an exception and some other times it does not...
I would suggest a different approach, if that is possible to change for you.
Instead of querying on each keystroke of the user, I would only do a query after, for example, 3 characters. Keep the result in some collection in memory.
After that, only do the next queries on the in-memory collection. That spares you any following database accesses that are always much slower and ou should get a considerable performance gain.
class Program
{
public class Person
{
public string Name;
public int Age;
}
public static void ExecuteQueryAsync ( IEnumerable<Person> collectionToQuery , Action<List<Person>> onQueryTerminated , out Action stopExecutionOfQuery )
{
var abort = false;
stopExecutionOfQuery = () =>
{
abort = true;
};
Task.Factory.StartNew( () =>
{
try
{
var query = collectionToQuery.Where( x =>
{
if ( abort )
throw new NotImplementedException( "Query aborted" );
// query logic:
if ( x.Age < 25 )
return true;
return
false;
} );
onQueryTerminated( query.ToList() );
}
catch
{
onQueryTerminated( null );
}
});
}
static void Main ( string[] args )
{
Random random = new Random();
Person[] people = new Person[ 1000000 ];
// populate array
for ( var i = 0 ; i < people.Length ; i++ )
people[ i ] = new Person() { Age = random.Next( 0 , 100 ) };
Action abortQuery;
ExecuteQueryAsync( people , OnQueryDone , out abortQuery );
// if after some time user wants to stop query:
abortQuery();
Console.Read();
}
static void OnQueryDone ( List<Person> results )
{
if ( results == null )
Console.WriteLine( "Query was canceled by the user" );
else
Console.WriteLine( "Query yield " + results.Count + " results" );
}
}
I had to execute the query like:
public IEnumerable<T> ExecuteQuery(IEnumerable<T> query)
{
foreach (var t in query)
{
if (counterOfSymultaneosQueries > 1)
{
// if there are more than two queries break from the last one
// breaking from it will decrease counterOfSymoltanosQueries
break;
}
yield return t;
}
}

Categories

Resources