[英]How to simplify or wrap exceptions when rewriting synchronous code to use TPL
Given an implementation as follows: 鉴于实施如下:
public class SomeServiceWrapper
{
public string GetSomeString()
{
try
{
//Do Something
}
catch (IOException e)
{
throw new ServiceWrapperException("Some Context", e);
}
catch (WebException e)
{
throw new ServiceWrapperException("Some Context", e);
}
}
}
The intention of the above is to enable the consumer of GetSomeString
to only need to catch ServiceWrapperException
. 上述目的是使GetSomeString
的使用者只需要捕获ServiceWrapperException
。
Consider the following approach to extending this with a similar async behaviour: 请考虑以下方法以使用类似的异步行为来扩展它:
public Task<string> GetSomeStringAsync()
{
Task<string>.Factory doSomething = ...
return doSomething.ContinueWith(x =>
{
if (x.IsFaulted)
{
if (x.Exception.InnerExceptions.Count() > 1)
{
throw new AggregateException(x.Exception);
}
var firstException = x.Exception.InnerExceptions[0];
if (typeof(firstException) == typeof(IOException)
|| typeof(firstException) == typeof(WebException))
{
throw new ServiceWrapperException("Some Context", firstException);
}
}
return x.Result;
}
}
This synchronous approach to wrapping exceptions doesn't fit naturally with the asynchronous approach. 这种包装异常的同步方法自然不适合异步方法。
What could the author of SomeServiceWrapper
do to simplify the exception handling code of any consumers so they only need to handle TradeLoaderException
instead of both IOException
and WebException
? SomeServiceWrapper
的作者可以做些什么来简化任何消费者的异常处理代码,这样他们只需要处理TradeLoaderException
而不是IOException
和WebException
?
I made an extension method that pretty much does that. 我做了一个扩展方法,几乎就是这样。 Usage: 用法:
public static Task<string> GetSomeStringAsync()
{
var doSomething = Task.Factory.StartNew(() => "bar");
return doSomething.WrapExceptions(typeof(IOException), typeof(WebException));
}
The Method: 方法:
public static Task<TResult> WrapExceptions<TResult>(this Task<TResult> task, params Type[] exceptionTypes)
{
return task.ContinueWith(_ =>
{
if (_.Status == TaskStatus.RanToCompletion) return _.Result;
if (_.Exception.InnerExceptions.Count > 1)
{
throw new AggregateException(_.Exception);
}
var innerException = _.Exception.InnerExceptions[0];
if (exceptionTypes.Contains(innerException.GetType()))
{
throw new ServiceWrapperException("Some Context", innerException);
}
throw _.Exception;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.