Parallel.ForEach 迭代中的操作超时 [英] Timeout for Action in Parallel.ForEach iteration
问题描述
我的代码中有类似的东西:
I have something similar to this in my code:
Parallel.ForEach(myList, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
Process(item);
});
问题是我在 Process()
方法中做了很多事情(连接到文件共享、解析文件、保存到数据库等),我担心可能会出错在这个过程中,迭代永远不会结束......这会发生吗?
The thing is that I do a bunch of things inside Process()
method (connect to a file share, parse a file, save to db, etc) and I worry that something might go wrong during this process making the iteration never finish...could this ever happen?
有没有办法为 Process()
方法设置超时时间以避免最终出现僵尸线程?
Is there a way to set a timeout for the Process()
method to avoid ending up having zombie threads?
更新:
我发现设置超时的最简单方法是向 CancellationTokenSource
添加毫秒或在任务上调用 Wait()
方法.
The easiest way I've found for setting a timeout is by adding milliseconds to a CancellationTokenSource
or calling the Wait()
method on a task.
选项#1
Parallel.ForEach(myList, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
var cts = new CancellationTokenSource(2000);
Task task = Task.Factory.StartNew(() => Process(item), cts.Token);
});
选项#2
Parallel.ForEach(myList, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
Task task = Task.Factory.StartNew(() => Process(item));
task.Wait(2000);
});
问题是这些选项都不能取消 Process()
方法.我是否需要检查 Process()
方法中的某些内容?
The problem is that none of those options are able to cancel the Process()
method. Do I need to check for something in the Process()
method?
推荐答案
我最终结合了这两个选项.它有效,但我不知道这是否是执行此操作的正确方法.
I ended up combining both options. It works but I don't know if this is the proper way to do this.
解决方案:
Parallel.ForEach(myList, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var token = tokenSource.Token;
Task task = Task.Factory.StartNew(() => Process(item, token), token);
task.Wait();
});
在 Process()
中,我多次检查取消:
and in Process()
I check for cancellation multiple times:
private void Process(MyItem item, CancellationToken token)
{
try
{
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();
...sentences
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();
...more sentences
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();
...etc
}
catch(Exception ex)
Console.WriteLine("Operation cancelled");
这篇关于Parallel.ForEach 迭代中的操作超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!