我想知道您是否认为这是处理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");
}
}
答案 0 :(得分:1)
如果您认为这是处理Parallel Loops抛出的异常的好方法......在任务中。
很难说'SomeProcess'。这取决于您的业务规则和技术问题的组合。
TPL有一个很好的机制来收集任务中的异常并亲[将它们交给调用者,所以想想你真正需要什么。
修改格式后编辑:
如果您确定您的循环应该在异常后继续下一个项目,那么您的 入队方法看起来可以接受。同样,它取决于循环正在做什么。