布尔值在 C# 中执行 Parallel.Foreach 时包含任务取消异常
Boolean Include Task Canceled Exception while doing Parallel.Foreach in C#
我有一个奇怪的情况,我无法找到以下堆栈跟踪的错误来源:
Message :One or more errors occurred.<br/>
StackTrace : at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body)
代码本身是一个简单明了的 Parallel.Foreach 循环,具有如下逻辑:
Parllel.Foreach(_collection, new ParallelOptions { MaxDegreeOfParallelism =5 }, item=>
{
// code inside
});
这个问题的根源可能是什么?你们对我有什么建议吗?我应该在哪里寻找?
@mortb 这就是我记录堆栈跟踪异常的方式:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Error.txt";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Message :" + ex.Message + "<br/>" + Environment.NewLine + "StackTrace :" + ex.StackTrace +
"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
}
您的 // code inside
抛出异常。您看到的异常是 Parallel.For
循环终止其工作任务以正确关闭。通常 ForEach
函数应该在最后抛出一个异常,该异常包含错误的实际原因。您看到的错误看起来像是调试器在 ForEach
函数的内部异常上触发。
对日志记录的提议更改:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Error.txt";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
foreach(var inner in (ex as AggregateException).?InnerExceptions ?? (new [] {ex}))
{
writer.WriteLine("Message :" + inner.Message + "<br/>" + Environment.NewLine + "StackTrace :" + inner.StackTrace +
"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
}
}
我有一个奇怪的情况,我无法找到以下堆栈跟踪的错误来源:
Message :One or more errors occurred.<br/>
StackTrace : at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body)
代码本身是一个简单明了的 Parallel.Foreach 循环,具有如下逻辑:
Parllel.Foreach(_collection, new ParallelOptions { MaxDegreeOfParallelism =5 }, item=>
{
// code inside
});
这个问题的根源可能是什么?你们对我有什么建议吗?我应该在哪里寻找?
@mortb 这就是我记录堆栈跟踪异常的方式:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Error.txt";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Message :" + ex.Message + "<br/>" + Environment.NewLine + "StackTrace :" + ex.StackTrace +
"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
}
您的 // code inside
抛出异常。您看到的异常是 Parallel.For
循环终止其工作任务以正确关闭。通常 ForEach
函数应该在最后抛出一个异常,该异常包含错误的实际原因。您看到的错误看起来像是调试器在 ForEach
函数的内部异常上触发。
对日志记录的提议更改:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\Error.txt";
using (StreamWriter writer = new StreamWriter(filePath, true))
{
foreach(var inner in (ex as AggregateException).?InnerExceptions ?? (new [] {ex}))
{
writer.WriteLine("Message :" + inner.Message + "<br/>" + Environment.NewLine + "StackTrace :" + inner.StackTrace +
"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
}
}