我正在尝试使用async CTP,即版本4.5,它允许使用异步方法而无需编写Begin/End方法。
我的第一次尝试是执行一个返回void的异步方法。我看了几个示例并进行了以下操作:
private void btnAsync01_Click(object sender, RoutedEventArgs e)
{
UpdateTxtLog("click button: " + System.DateTime.Now);
method01Async();
UpdateTxtLog("after ethod01Async: " + System.DateTime.Now);
}
private async void method01Async()
{
await TaskEx.Run(() =>
{
UpdateTxtLog("Enter method01Async: " + System.DateTime.Now);
Thread.Sleep(10000);
UpdateTxtLog("exit method01Async: " + System.DateTime.Now);
});
}
在我的WPF项目中,我有一个文本框用于查看结果和一个按钮来执行异步方法。
在异步方法中,我使用await,这是必需的,因为该方法是异步的,并且使用TaskEx.Run来创建一个新线程以执行代码。
我的疑问就在这里。 在我看过的一些关于如何创建返回void的异步方法的例子中,都是使用Task.Run或TaskEx.Run。
如果我没有错的话,Task.Run会创建一个新线程来执行该方法。那么,如果使用Task创建一个新线程,我可以实现不阻塞主线程,那么为什么还要使用异步方法呢?
此外,如果异步方法访问某些共享变量,我必须小心并发问题,对吧?所以我不知道使用异步方法的优势,至少在这种情况下是这样的。
事实上,我使用相同的代码而没有使用异步和等待,结果是一样的,主程序没有被阻塞,所有内容都按照我的预期工作。该方法如下:
private void method01Async()
{
TaskEx.Run(() =>
{
UpdateTxtLog("Enter method01Async: " + System.DateTime.Now);
Thread.Sleep(10000);
UpdateTxtLog("Exit method01Async: " + System.DateTime.Now);
});
}
我的问题是,当方法返回void时,这是使用async的正确方式吗?
async
方法都返回Task
或Task<TResult>
,除非它们是事件处理程序并且必须返回void
。这样可以在需要时组合它们,并且错误处理也更加清晰(如果一个async void
方法在WPF上下文中引发异常,则会直接发送到UI消息循环,因此async void
方法并不真正是“fire and forget”)。 - Stephen ClearyTask.Run
在线程池上运行代码。您可以使用Task.Delay
进行异步等待,而不是排队阻塞的Sleep
。 - Stephen Cleary