使用带有结果的异步版本实现功能 [英] Implementing function using async version with Result
问题描述
我正在实现函数的异步版本和普通版本.我已经实现了异步版本.对于普通版本,我可以复制粘贴并将异步函数调用的用法替换为其普通对应部分.或者,我可以使用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屋!