Ron*_*ean 0 .net c# async-await
这是我的事件处理程序代码:
protected async void TestrunSaveExecute()
{
bool saveResult = await SaveTestRunAsync();
}
Run Code Online (Sandbox Code Playgroud)
为了保持UI响应,我使用了async
/ await
方法.
根据我的理解,我现在可以在SaveTestRunAsync()
不阻止UI的情况下进行一些冗长的操作,因为它通过使用await
关键字解耦.
private async Task<bool> SaveTestRunAsync()
{
//System.Threading.Thread.Sleep(5000); --> this blocks the UI
await Task.Delay(5000); // this doesn't block UI
return true;
}
Run Code Online (Sandbox Code Playgroud)
你能否解释为什么Thread.Sleep
仍然阻止用户界面的呼叫,而Task.Delay
不是?
ang*_*son 14
代码仍在UI线程上运行.
它不是在后台线程上运行.
因此,您在异步方法中执行的任何冗长,昂贵的操作仍将阻止该时间段的UI.
Thread.Sleep
将UI线程置于休眠状态.
你需要了解如何async
以及await
在这种情况下工作.
await
这里基本上说这个:
我们在这里将方法拆分为两个.第一部分是任何执行到达的点
await
.第二部分是等待对象完成后应该执行的任何部分.
所以,基本上,该方法一直执行直到达到await Task.Delay(5000);
.然后它将"延迟5秒"置于播放状态,并说"在完成后安排其余代码执行".然后它返回,以便UI线程可以保持泵送消息.
一旦5秒钟结束,UI线程将执行该方法的其余部分.
基本上,如果您执行异步I/O,这是很好的,但如果您执行昂贵的操作(如处理大型数据集或类似操作)则不太好.
那么你怎么能这样做呢?
你可以用Task.Run
.
这将启动另一个线程来执行它给出的委托,并且UI线程可以在此期间自由地执行其他操作.
基本上你可以想到一个方法使用await
如下:
Life of method: <------------------------------------------------------->
Parts: [ start of method ----][awaitable][ rest of method -----]
Run Code Online (Sandbox Code Playgroud)
因此该方法将执行第一部分,直到它到达await X
,然后它将检查X是否已经完成,如果没有完成,它将Task
以awaitable
对象开始运行的方式设置一些对象,并且一旦完成,"方法的其余部分"开始运行.
如果X已经完成,也许它是一个已经完成的异步I/O操作,或者它完成得非常快,那么该方法将继续执行方法的其余部分,就好像你没有await
在那里写的那样.
但如果没有,那么它就会回归.这很重要,因为它允许UI线程(在这种情况下)回到用户点击鼠标点击和事物等消息.
一旦等待那个"等待对象"的任务被告知等待完成,就会安排"方法的其余部分",这基本上(在这种情况下)将消息放入消息队列中,要求它执行其余部分方法.
越多await
的语句,你有这样的方法,将多件,基本上它只会分裂法成多个部分.
您可以Task
使用早期.NET版本中引入的类来完成所有这些操作.async
/ 的全部目的await
是使编写代码更容易,因为将代码包装在任务对象中会产生令人遗憾的影响,即将代码转换为异常,并使处理异常和循环等事情变得困难.
归档时间: |
|
查看次数: |
517 次 |
最近记录: |