使用带有结果的异步版本实现功能 [英] Implementing function using async version with Result

查看:109
本文介绍了使用带有结果的异步版本实现功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现函数的异步版本和普通版本.我已经实现了异步版本.对于普通版本,我可以复制粘贴并将异步函数调用的用法替换为其普通对应部分.或者,我可以使用Result调用异步版本,如下所示.

I am implementing both async and normal versions of a function. I've already implemented async version. For the normal version I can copy-paste and replace usage of async function calls with their normal counter-parts. Or I can call the async version with Result as in follows.

第一种方法:

public int SomeTask(int param) 
{
   //Something going on
   return SomeOtherTask();
} 

public async Task<int> SomeTaskAsync(int param) 
{
   //Something going on (copy pasted)
   return await SomeOtherTaskAsync();    
} 

第二种方法:

public int SomeTask(int param) 
{
   return SomeTaskAsync(param).Result;
} 

public async Task<int> SomeTaskAsync(int param) 
{
   //some function calls with await
} 

第二种方法可能存在问题吗?

Is there a possible problem with second approach?

推荐答案

性能会受到影响.到底有多少是不可能的-您就是代码中的一员,您可以针对您的确切用例进行性能分析.

Performance will be impacted. How much is impossible to tell - you're the one with the code, you can do the profiling for your exact use case.

但是,制作仅调用Result的方法的同步版本没有意义-方法的用户可以执行相同的操作.问题是,无论如何都要这样做很危险,尤其是在涉及同步上下文的情况下.考虑示例代码:

However, there's no point in making a sync version of the method that only calls Result - the user of your method can do the same thing. The problem is, it can be quite dangerous to do that anyway, especially when synchronization contexts are involved. Consider the sample code:

async void btnTest_Click(object sender, EventArgs e)
{
  await DoSomethingAsync();
}

async Task DoSomethingAsync()
{
  await Task.Delay(1000);
}

这很好.现在,让我们尝试您的同步"版本:

This works fine. Now, let's try your "sync" version:

async void btnTest_Click(object sender, EventArgs e)
{
  DoSomethingAsync().Result;
}

async Task DoSomethingAsync()
{
  await Task.Delay(1000);
}

糟糕,您陷入僵局. UI线程正在等待DoSomethingAsync完成,但是DoSomethingAsync需要完成在UI线程上的执行.如果您同步等待async方法,则永远无法假设它会运行.

Oops, you have a deadlock. The UI thread is waiting for DoSomethingAsync to finish, but DoSomethingAsync needs to finish executing on the UI thread. You can never assume that an async method will run if you wait for it synchronously.

此外,通过使用Result而不是await,您将失去很多异常处理功能.例如,异常堆栈跟踪将全部混乱,您将需要处理创建任务的方法和Result调用本身引发的异常-第一个将引发异常直至第一个await实际上必须等待,第二个用于所有继续.你永远都不知道是哪个.

Also, by using Result instead of await, you lose a lot of the exception handling capabilities. For example, the exception stack trace is going to be all messed up, and you'll need to handle exceptions thrown by both the method that creates the task and the Result call itself - the first will throw exceptions up to the point of the first await that actually has to wait, and the second for all the continuations. You never know which is which.

这篇关于使用带有结果的异步版本实现功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆