Обработка исключений в задачах и параллельных циклах.(Threading - TPL) - PullRequest
2 голосов
/ 29 сентября 2011

Я хочу знать, считаете ли вы, что это хороший способ обработки исключений, создаваемых параллельными циклами (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");
    }

}

1 Ответ

1 голос
/ 29 сентября 2011

, если вы считаете, что это хороший способ обработки исключений, генерируемых параллельными циклами ... внутри задач.

Трудно сказать для SomeProcess.Это зависит от сочетания ваших бизнес-правил и технических проблем.

TPL обладает отличным механизмом сбора исключений внутри задач и передачи их вызывающей стороне, поэтому подумайте, что вам действительно нужно.


Правка после исправления форматирования:

Если вы действительно уверены, что ваш цикл должен продолжаться со следующего элемента после исключения, тогда ваш подход к постановке в очередь выглядит приемлемым.Опять же, это зависит от того, что делает цикл.

...