gpt4 book ai didi

c# - 使用异步代码时获得有意义的堆栈跟踪

转载 作者:IT王子 更新时间:2023-10-29 04:11:12 27 4
gpt4 key购买 nike

我已经创建了一小段代码来并行运行多个异步操作(Parallel 类本身不适合异步操作)。

看起来像这样:

public static async Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
var chunks = source.Chunk(dop);
foreach (var chunk in chunks)
await Task.WhenAll(chunk.Select(async s => await body(s).ContinueWith(t => ThrowError(t))));
}

private static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
while (source.Any())
{
yield return source.Take(chunksize);
source = source.Skip(chunksize);
}
}

private static void ThrowError(Task t)
{
if (t.IsFaulted)
{
if (t.Exception.InnerExceptions != null && t.Exception.InnerExceptions.Count == 1)
throw t.Exception.InnerExceptions[0];
else
throw t.Exception;
}
}

就并行运行任务而言,上述代码运行良好。但是,当抛出异常时,我确实遇到了一些问题。

就返回异常消息而言,异常捕获代码工作良好,但堆栈跟踪还有很多不足之处 - 因为它指向 ThrowError 方法,而不是最初产生异常。我可以按照自己的方式工作,找出附加的调试器出了什么问题,但如果我发布这个应用程序,我将无法使用该选项——充其量,我将记录堆栈跟踪的异常。

那么 - 有什么方法可以在运行异步任务时获得更有意义的堆栈跟踪吗?

附言。这是针对 WindowsRT 应用程序的,但我认为问题不仅限于 WindowsRT 本身......

最佳答案

So - is there any way to get a more meaningful stack trace when running async tasks?

是的,您可以使用 .NET 4.5 中引入的 ExceptionDispatchInfo.Capture 专门用于异步等待:

private static void ThrowError(Task t)
{
if (t.IsFaulted)
{
Exception exception =
t.Exception.InnerExceptions != null && t.Exception.InnerExceptions.Count == 1
? t.Exception.InnerExceptions[0]
: t.Exception;

ExceptionDispatchInfo.Capture(exception).Throw();
}
}

"You can use the ExceptionDispatchInfo object that is returned by this method at another time and possibly on another thread to rethrow the specified exception, as if the exception had flowed from this point where it was captured to the point where it is rethrown. If the exception is active when it is captured, the current stack trace information and Watson information that is contained in the exception is stored. If it is inactive, that is, if it has not been thrown, it will not have any stack trace information or Watson information."

但是,请记住,异步代码中的异常通常没有您希望的那么有意义,因为所有异常都是从编译器生成的状态机上的 MoveNext 方法内部抛出的。

关于c# - 使用异步代码时获得有意义的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33994783/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com