작업 내에서 병렬 루프 (Parallel.ForEach 및/또는 Parallel.For)에 의해 발생한 예외를 처리하는 좋은 방법이라고 생각하는지 알고 싶습니다.작업 및 병렬 루프의 예외 처리. (Threading - TPL)
나는 그렇게 나쁘지 않다고 생각하지만, 내 의견은 유용 할 수 있습니다! 당신이 내게 어떤 빛을 던질 수 있기를 바랍니다!
(나는 물론, 프레임 워크 4.0을 VS2010를 사용)
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");
}
}
예, 반복이 예외를 throw하더라도 mi 루프가 계속되어야합니다. 각 반복은 일부 객체 상태 (예 : 웹 서비스 호출 또는 데이터베이스 쿼리)를 업데이트하고 비즈니스 규칙으로 인해 병렬로 수행해야합니다. – Pato
고마워요! :) – Pato