【发布时间】:2012-02-11 12:34:44
【问题描述】:
我正在尝试做相当于 dollowing C# 5 伪代码:-
async Task<int> CallAndTranslate()
{
try
{
return await client.CallAsync();
} catch(FaultException ex) {
if (ex.FaultCode ...)
throw new Exception("translated");
}
}
Given an arbitrary Task which does not return a result, translating exceptions 当从 C# 5 向后移植很容易时using the technique supplied by @Drew Marsh
这种技术不能简单地推广到Task<T>,因为Task.ContinueWith 的任何重载我可以看到返回一个秃头Task,而不是Task<T>。
有没有办法使用 TPL API 来实现这一点而无需求助于:
- 将其包装在另一个
Task<T>中 - 导致异常通过异常处理机制被抛出和捕获
- 在初始回答后添加......如果不翻译异常,则应单独保留堆栈跟踪
这是我天真的占位符实现:
public class TranslatingExceptions
{
Task<int> ApiAsync()
{
return Task<int>.Factory.StartNew( () => {
throw new Exception( "Argument Null" ); } );
}
public Task<int> WrapsApiAsync()
{
return ApiAsync().TranslateExceptions(x=>{
if (x.Message == "Argument Null" )
throw new ArgumentNullException();
});
}
[Fact]
public void Works()
{
var exception = Record.Exception( () =>
WrapsApiAsync().Wait() );
Assert.IsType<ArgumentNullException>( exception.InnerException );
}
}
以下Task<T> 扩展实现了我的占位符实现:
static class TaskExtensions
{
public static Task<T> TranslateExceptions<T>( this Task<T> task, Action<Exception> translator )
{
// TODO REPLACE NAIVE IMPLEMENTATION HERE
return Task<T>.Factory.StartNew( () =>
{
try
{
return task.Result;
}
catch ( AggregateException exception )
{
translator( exception.InnerException );
throw;
}
} );
}
}
【问题讨论】:
标签: .net asynchronous exception-handling task-parallel-library