[英]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.
因此,我有一个符号列表,如AAPL,FB,QQQ,MSFT,IBM,而且我还有一个函数,其中包含给定符号的计算逻辑。 So perform my this logic I am using Task.
因此,请执行我使用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.
我已经在google上检查过,这是因为索引超出范围。 I have checked by set debugger but I not understand how to check it for task regions.
我已经通过设置调试器进行了检查,但是我不明白如何检查任务区域。
Parallel.Foreach
can do this. Parallel.Foreach
可以做到这一点。 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
控制呼叫:
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). 首先,在这种情况下(如果您写入集合),我将使用并发集合
ConcurrentBag
。 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.WhenAll
与await
关键字一起使用。 Task.WaitAll
can create a deadlock. Task.WaitAll
可以创建死锁。 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. 除了您有非法代码(
symbolList.IndexOf(i)
应该是symbolList[i]
)的事实之外,您面临的问题是在调用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];
注意,行
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. 如果不这样做,循环将在任务开始之前完成,然后
i
等于taskArray.Length
,因此会出现“索引超出范围”错误。
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;
我建议的另一个建议是,您应该使用Microsoft的Reactive Framework(aka Rx)-NuGet
System.Reactive
并using System.Reactive.Linq;
添加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.
然后,您也可以对结果使用LINQ运算符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.