使用任务并行库 a la wait 转换 void 任务的异常
我需要以与正常同步代码执行以下操作相同的方式转换从 Task
发出的异常:
try {
client.Call();
} catch(FaultException ex) {
if (ex.<Some check>)
throw new Exception("translated");
}
但是,我想异步执行此操作,即 Call<上面的 /code> 实际上是
Task CallAsync()
。
因此,在 C# 5 中,我的方法将如下所示:
async Task CallAndTranslate()
{
try{
await client.CallAsync();
} catch(FaultException ex) {
if (ex.FaultCode ...)
throw new Exception("translated");
}
}
但我现在使用 C# 4。
那么,如果我想触发一个任务,但要转换 (TPL) 故障,然后再次将整个事件作为 Task
公开,我该怎么办?
- 最初源自 WCF Web 服务,但这在这里并不重要
编辑:更具体的说法:
public class TranslatingExceptions
{
public Task ApiAsync() // The inner layer exposes it exactly this way
{
return Task.Factory.StartNew(()=>{ throw new Exception( "Argument Null" );});
}
public Task WrapsApiAsync() // this layer needs to expose it exactly this way
{
// async preview pseudocode for what I need to do
try {
await ApiAsync( );
} catch (Exception exception){
if( exception.Message == "Argument Null" )
throw new ArgumentNullException();
}
}
[Fact]
public void Works()
{
var exception = Record.Exception( () =>
WrapsApiAsync().Wait());
Assert.IsType<ArgumentNullException>( exception.InnerException);
}
}
如何在不需要 C# 5 的情况下实现 WrapsApiAsync()
?
I need to translate an exception emanating from a Task<T>
in the same manner that doing the following would for normal synchronous code:
try {
client.Call();
} catch(FaultException ex) {
if (ex.<Some check>)
throw new Exception("translated");
}
However, I want to do this asynchronously, i.e., Call
above is actually Task CallAsync()
.
So in C# 5 my method would look like this:
async Task CallAndTranslate()
{
try{
await client.CallAsync();
} catch(FaultException ex) {
if (ex.FaultCode ...)
throw new Exception("translated");
}
}
But I'm using C# 4 for now.
So what can I do given that I want to trigger a Task but have the (TPL) Fault be translated and then expose the whole thing once again as a Task<T>
?
- originally emanating from a WCF webservice but that's not important here
EDIT: A slightly more concrete way of saying it:
public class TranslatingExceptions
{
public Task ApiAsync() // The inner layer exposes it exactly this way
{
return Task.Factory.StartNew(()=>{ throw new Exception( "Argument Null" );});
}
public Task WrapsApiAsync() // this layer needs to expose it exactly this way
{
// async preview pseudocode for what I need to do
try {
await ApiAsync( );
} catch (Exception exception){
if( exception.Message == "Argument Null" )
throw new ArgumentNullException();
}
}
[Fact]
public void Works()
{
var exception = Record.Exception( () =>
WrapsApiAsync().Wait());
Assert.IsType<ArgumentNullException>( exception.InnerException);
}
}
How would you implement WrapsApiAsync()
without needing C# 5?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,现在我完全清楚您在寻找什么,这就是您在 4.0 中构建等效项所需要做的所有事情:
这应该可以实现您正在寻找的内容。需要注意的一件事是,我在创建延续时使用
TaskContinuationOptions.ExecuteSynchronously
。这是因为这项工作很小而且很紧张,您不希望因为等待调度程序从线程池中取出整个其他线程来执行此检查而产生开销。Ok, so now that I'm entirely clear on what you're looking for, here's all you would need to do to build the equivalent in 4.0:
This should accomplish what you're looking for. One thing to note is that I use
TaskContinuationOptions.ExecuteSynchronously
when creating the continuation. This is because this work is small and tight and you don't want to incur the over head of waiting for a whole other thread having to be picked up from the thread pool by the scheduler just to do this check.