我正在写一些等待的方法,我在互联网上找到了很多方法。所以我来到这里是为了了解每一条路上到底发生了什么,以及是否必须放弃某些方法。
据我所知,有两种等待方法:
public async Task<Foo> GetFooAsync()
{
var foo = await TrulyGetFooAsync();
// Do stuff with foo
return foo;
}
我没有找到任何其他方法来做到这一点,我认为这是正确的方法。告诉我,如果我错了!
这里出现了问题。
例如,我看到了这个:
public async Task<Foo> GetFooAsync()
{
return await Task.Run(() => TrulyGetFoo());
}
据我了解,async / await关键字是无用的,可以避免这样做:
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
???
但我最近发现了这种方式:
public Task<Foo> GetFooAsync()
{
TaskCompletionSource<Foo> tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(TrulyGetFoo());
return tcs.Task;
}
如果我理解正确,一个等待的方法并不总是在另一个线程上运行???我的猜测是第三个例子是提供这种机制(但是如何在第三个例子中看到同步代码),当示例1和2总是在工作线程上运行时???
可能还有另外一种方法来编写等待方法,所以让我知道它们。
答案 0 :(得分:3)
简短版本是这样的:可以在async
代码块中等待返回任务的任何内容。
public async Task MyAsyncMethod()
{
// do some stuff
await TrulyAsyncFoo();
// do some other stuff
return;
}
如果等待异步调用是方法所做的唯一事情,您可以简单地返回任务本身,这将等待&#34;上游&#34;:
public Task MyAsyncMethod()
{
return TrulyAsyncFoo();
}
至于在异步方法中调用同步(非异步)代码,它没有任何意义。只需将其称为普通代码:
public async Task MyAsyncMethod()
{
MySyncMethod();
await TrulyAsyncFoo();
MyOtherSyncMethod();
}
做Task.Run(() => Foo())
几乎总是代码味道,你不能做异步/等待。编写异步代码与编写多线程代码不同。 Async只是告诉编译器你需要等待一些网络或IO绑定任务完成的好方法。
总结一下:
Task
或Task<T>
async void
task.Wait()
和task.Result
进行阻止,除非您知道自己在做什么答案 1 :(得分:2)
例如,我看到围绕同步代码的[
Task.Run
包装器]
This is a bad practice。我有一篇博文解释why Task.Run
should not be used as a method implementation。
据我了解,async / await关键字是无用的,可以避免
是的,但是I don't recommend eliding async
/await
in more complex methods。
我最近找到[
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。
答案 2 :(得分:-3)
我将此用于操作我的数据库的异步事件
private async void btnSave_Click(object sender, EventArgs e)
{
success = await someClass.someMethod(some args);
}
和someMethod就是这样的任务:
public static async Task<someObject> someMethod(args)
{
//do something here
}