繁体   English   中英

在任务和并行循环中处理异常。 (线程-TPL)

[英]Handling Exceptions in Tasks and Parallel loops. (Threading - TPL)

我想知道您是否认为这是处理Tasks中的并行循环(Parallel.ForEach和/或Parallel.For)引发的异常的好方法。

我认为还不错,但是您的意见对我很有用! 希望你能给我一些启示!

(我使用了VS2010,当然也使用了Framework 4.0)

class Program
{
    private static ConcurrentQueue<Exception> _exceptions = new ConcurrentQueue<Exception>();
    private static readonly ExceptionManager _exceptionManager = new ExceptionManager();

    static void Main()
    {
        var process = new SomeProcess(_exceptions);
        var otherProcess = new SomeOtherProcess(_exceptions);

        var someProcess = new Task(() =>
                                       {
                                           process.InitSomeProcess(); 
                                           process.DoSomeProcess();
                                       });

        var someOtherProcess = new Task(() =>
                                            {
                                                otherProcess.InitSomeOtherProcess();
                                                otherProcess.DoSomeOtherProcess();
                                            });
        someProcess.Start();
        someOtherProcess.Start();

        try
        {
            someProcess.Wait();
            someOtherProcess.Wait();
        }
        catch ( Exception ex)
        {
            _exceptionManager.Manage(ex);
        }
        finally
        {
            Console.WriteLine();

            foreach ( var exception in _exceptions )
            {
                _exceptionManager.Manage(exception);
            }
            _exceptions = new ConcurrentQueue<Exception>(); //Delete exceptiones to prevent manage them twice (maybe this could be one in a more elegant way).
        }
        Console.ReadKey();
    }
}

public class ExceptionManager
{
    public void Manage(Exception ex)
    {
        Console.WriteLine("Se dió una {0}: {1}", ex.GetType(), ex.Message);
    }
}


public class SomeProcess
{
    private readonly ConcurrentQueue<Exception> _exceptions;

    public SomeProcess(ConcurrentQueue<Exception> exceptions)
    {
        _exceptions = exceptions;
    }

    public void InitSomeProcess()
    {
        Parallel.For(0, 20, (i, b) =>
                                {
                                    try
                                    {
                                        Console.WriteLine("Initializing SomeProcess on {0}.", i);
                                        throw new InvalidOperationException("SomeProcess was unable to Initialize " + i);
                                    }
                                    catch (Exception ex)
                                    {
                                        _exceptions.Enqueue(ex);
                                    }
                                });

        Console.WriteLine("SomeProcess initialized :D");
    }

    public void DoSomeProcess()
    {
        Parallel.For(0, 20, (i, b) =>
                                {
                                    try
                                    {
                                        Console.WriteLine("Doing SomeProcess on {0}.", i);
                                        throw new InvalidOperationException("SomeProcess was unable to process " + i);
                                    }
                                    catch (Exception ex)
                                    {
                                        _exceptions.Enqueue(ex);
                                    }
                                });

        Console.WriteLine("SomeProcess done :D");
    }


}

public class SomeOtherProcess
{

    private readonly ConcurrentQueue<Exception> _exceptions;

    public SomeOtherProcess(ConcurrentQueue<Exception> exceptions)
    {
        _exceptions = exceptions;
    }

    public void InitSomeOtherProcess()
    {
        Parallel.For(0, 20, (i, b) =>
                                {
                                    try
                                    {
                                        Console.WriteLine("Initializing SomeOtherProcess on {0}.", i);
                                        throw new InvalidOperationException("SomeOtherProcess was unable to Initialize " + i);
                                    }
                                    catch (Exception ex)
                                    {
                                        _exceptions.Enqueue(ex);
                                    }
                                });

        Console.WriteLine("SomeOtherProcess initialized :D");
    }

    public void DoSomeOtherProcess()
    {
        Parallel.For(0, 20, (i, b) =>
                                {
                                    try
                                    {
                                        Console.WriteLine("Doing SomeOtherProcess on {0}.", i);
                                        throw new InvalidOperationException("SomeOtherProcess was unable to process " + i);
                                    }
                                    catch (Exception ex)
                                    {
                                        _exceptions.Enqueue(ex);
                                    }
                                });

        Console.WriteLine("SomeOtherProcess done! :D");
    }

}

如果您认为这是处理Tasks中Parallel Loops引发的异常的好方法。

很难说出“ SomeProcess”。 这取决于您的业务规则和技术问题。

TPL具有出色的机制,可以在Tasks中收集异常并将其传播给调用者,因此请考虑一下您真正需要什么。


固定格式后,编辑:

如果您确实确定异常之后循环应该继续下一个项目,那么排队方法看起来可以接受。 同样,这取决于循环的作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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