我正在编写一些可等待的方法,并且我在互联网上找到了很多这样做的方法。所以我来这里是为了了解每条路到底发生了什么,以及是否必须取消某些路。
据我所知,有两种可等待的方法:
那些调用其他可等待方法的:
public async Task<Foo> GetFooAsync()
{
var foo = await TrulyGetFooAsync();
// Do stuff with foo
return foo;
}
我没有找到任何其他方法来做到这一点,我认为这是正确的方法。如果我错了告诉我!
那些只调用非等待方法的:
我想到了这些问题。
例如,我看到了这个:
例1
public async Task<Foo> GetFooAsync()
{
return await Task.Run(() => TrulyGetFoo());
}
据我所知,async/await 关键字是无用的,可以避免给出这个:
例2
public Task<Foo> GetFooAsync()
{
return Task.Run(() => TrulyGetFoo());
}
最后一个例子是我到目前为止所做的。关于这一点,两者之间有区别吗:
Task.Run(() => TrulyGetFoo());
和
Task.Run((Foo)TrulyGetFoo); // I don't know if the cast is required at any time but in my code, it was
???
但是我最近发现是这样的:
例3
public Task<Foo> GetFooAsync()
{
TaskCompletionSource<Foo> tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(TrulyGetFoo());
return tcs.Task;
}
如果我理解正确,可等待的方法并不总是在另一个线程上运行???我的猜测是第三个示例提供了这种机制(但如何???我只在第三个示例中看到同步代码),而示例 1 和 2 将始终在工作线程上运行???
可能还有其他方法可以编写可等待的方法,让我知道吧。
最佳答案
For example, I saw [
Task.Run
wrappers around synchronous code]
This is a bad practice .我有一篇博文解释了 why Task.Run
should not be used as a method implementation .
As far as I understand, the async/await keywords are useless and can be avoided
是的,但是 I don't recommend eliding async
/ await
in more complex methods .
I recently found [
TaskCompletionSource<T>
]
如评论中所述,您的代码示例仍然是同步的。
要使其异步,您的代码应该开始一些操作并返回 TaskCompletionSource<T>.Task
.然后,每当该操作完成时,您的完成处理程序应调用 TaskCompletionSource<T>.SetResult
(或类似的方法)。有关示例,请参阅 TAP wrappers for EAP或 TAP wrappers for WaitHandle
s .
TaskFactory.FromAsync
也是 TaskCompletionSource<T>
的包装器, 并用于 TAP wrappers for APM .
关于c# - 如何正确创建可等待的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43393169/