gpt4 book ai didi

c#-4.0 - 根据非并行任务实现同步方法的模式(翻译/展开聚合异常)

转载 作者:行者123 更新时间:2023-12-02 19:03:39 25 4
gpt4 key购买 nike

我有一个返回任务的异步方法。

我还希望提供一个同步等效项,但我不希望它的使用者必须去解压 AggregateException

现在我明白整个想法是你不能以一般方式任意选择一篇,而且我知道我可以去阅读更多 Stephen Toub 的文章(我会的,但不是现在),我会理解的一切都可以自己决定。

在此期间,我想利用这样一个事实:我的任务实际上只是链接的“工作流”,没有并行性,只是干预等待(不,不是 TPL 数据流),这不应导致多个异常。在这种情况下,按如下方式处理是否合适:

    CallAsync().Wait();
}
catch( AggregateException ae)
{
throw ae.Flatten().First()

或者我保证AggregateException总是有一个InnerException,即使有多个。或者是否存在我应该回退到 .Flatten().First() 的情况?

<小时/>

在一些 TPL 文档中,我看到对 AggregateException 上的 Unwrap() 方法的引用(不确定它是扩展还是测试版中的某些内容)。

作为占位符,我正在做:

void Call( )
{
try
{
CallAsync().Wait();
}
catch ( AggregateException ex )
{
var translated = ex.InnerException ?? ex.Flatten().InnerExceptions.First();
if ( translated == null )
throw;
throw translated; }
}

Task CallAsync(){ ...

最佳答案

据我所知,没有“干净”的方法可以做到这一点。您不能使用 throw someInnerException; 因为无论异常在异步工作流程中发生的位置,您都会丢失堆栈,如果您只使用 throw; ,您显然会传播AggregateException。对于同步方法,您必须做的是拥有某种“包装”异常,您可以将 AggregateException 的第一个异常填充到其中,然后从该方法的同步版本一致地抛出该异常。

void Call()
{
try
{
CallAsync().Wait();
}
catch (AggregateException ex)
{
throw new MyConsistentWrapperException("An exception occurred while executing my workflow. Check the inner exception for more details.", ex.Flatten().InnerExceptions.First());
}
}

FWIW,他们在 4.5 中用 the new ExceptionDispatchInfo class 解决了这个问题这将帮助您跨线程编码(marshal)异常,而无需破坏堆栈。然后你可以像这样编写同步版本:

void Call()
{
try
{
CallAsync().Wait();
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.Flatten().InnerExceptions.First()).Throw();
}
}

关于c#-4.0 - 根据非并行任务实现同步方法的模式(翻译/展开聚合异常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8853693/

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