Parallel.ForEach 迭代中的操作超时 [英] Timeout for Action in Parallel.ForEach iteration

查看:21
本文介绍了Parallel.ForEach 迭代中的操作超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码中有类似的东西:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆