简体   繁体   中英

How to run single process for multiple values in c#?

I need to run single process for list of symbols. So I have a list of symbols like AAPL, FB, QQQ, MSFT, IBM and also I have a function which contains logic of calculations for given symbol. So perform my this logic I am using Task.

List<string> symbolList = new List<string>() {"AAPL","QQQ","FB","MSFT","IBM"};
Task[] taskArray = new Task[symbolList.Count];
for(int i=0; i<taskArray.Length; i++)
{
   taskArray[i] = Task.Factory.StartNew(() =>
       {
          criteriaEvalution.Evaluate(finalArray, false, new List<parseObj>(), ref builder, symbolList.IndexOf(i));
       });
}
Task.WaitAll(taskArray);

So when I am running this code then it's showing me error like

Index was out of range. Must be non-negative and less than the size of the collection.

Error is showing on line:

criteriaEvalution.Evaluate(finalArray, false, new List<parseObj>(), ref builder, symbolList.IndexOf(i));

where I am going to pass symbol name to the function.

So please can I get a solution for this? I have checked on google for this it's saying for the index is out of range. I have checked by set debugger but I not understand how to check it for task regions.

Parallel.Foreach can do this. Here an example how to:

public static void DoIt(string a)
{
    Console.WriteLine(a);
}

public static void Main(string[] args)
{
    List<string> symbolList = new List<string>() { "AAPL", "QQQ", "FB", "MSFT", "IBM" };
    Parallel.ForEach(symbolList, a => DoIt(a));
}

You can control the call by using ParallelOptions :

ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = 10 };
Parallel.ForEach(symbolList, options, a => DoIt(a));

First, I would use the concurrent collection ConcurrentBag in this case(if you write into the collection). Concurrent collections are going to lock the instance when multiple threads are about to access it. Also, I would suggest using Task.WhenAll with await keyword. Task.WaitAll can create a deadlock. So here is a sample you can try out:

public static async Task Main()
{
    var symbolList = new ConcurrentBag<string> { "AAPL", "QQQ", "FB", "MSFT", "IBM" };
    var taskArray = new List<Task>();

    foreach (var s in symbolList)
    {
        var task = Task.Run(() =>
        {
            Process(s);
        });

        taskArray.Add(task);
    }

    await Task.WhenAll(taskArray);
}

Probably you should replace:

symbolList.IndexOf(i)

...with:

symbolList[i]

Apart from the fact that you've got illegal code ( symbolList.IndexOf(i) should probably be symbolList[i] ) the issue you're facing is that you're not capturing the loop variable before you call the lambda.

Here's the simple fix:

List<string> symbolList = new List<string>() { "AAPL", "QQQ", "FB", "MSFT", "IBM" };
Task[] taskArray = new Task[symbolList.Count];
for (int i = 0; i < taskArray.Length; i++)
{
    string symbol = symbolList[i];
    taskArray[i] = Task.Factory.StartNew(() =>
    {
        criteriaEvalution.Evaluate(finalArray, false, new List<parseObj>(), ref builder, symbol);
    });
}
Task.WaitAll(taskArray);

Note the line string symbol = symbolList[i]; before you start the task.

If you don't do this the loop finishes before the tasks start and then i is equal to taskArray.Length and hence you get the "Index was out of range" error.

The other this I'd suggest is you should use Microsoft's Reactive Framework (aka Rx) - NuGet System.Reactive and add using System.Reactive.Linq; - then you can do this:

List<string> symbolList = new List<string>() { "AAPL", "QQQ", "FB", "MSFT", "IBM" };

var query =
    from symbol in symbolList.ToObservable()
    from e in Observable.Start(() =>
        criteriaEvalution.Evaluate(finalArray, false, new List<parseObj>(), ref builder, symbol))
    select e;

query.ToArray().Wait();

Much simpler and cleaner than tasks. Then you can use LINQ operators on the results too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM