Kev*_*lia 1 c# asynchronous async-await
我很困惑为什么这两个程序的输出有所不同:
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 33; i++)
{
await LongProcess();
}
}
private async Task LongProcess()
{
await Task.Delay(1000);
progressBar1.Value += 3;
}
Run Code Online (Sandbox Code Playgroud)
和
private async void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 33; i++)
{
await Task.Run(() => LongProcess());
}
}
private async void LongProcess()
{
await Task.Delay(1000);
progressBar1.Value += 3;
}
Run Code Online (Sandbox Code Playgroud)
我意识到返回的第一个例子Task
更正确,但我不明白为什么在a Task.Run
中包装void函数不会产生相同的输出?第一个功能完成我的预期,每1秒更新一次进度条.第二个代码尝试一次更新进度条,导致尝试从多个线程更新相同的UI元素时出现问题.
我的假设是,因为buttonClick方法等待漫长的过程完成,所以两组代码都不允许progressBar1更新发生,直到前一个过程完成.为什么第二组代码允许它同时发生?
这不符合你的想法:
await Task.Run(() => LongProcess());
Run Code Online (Sandbox Code Playgroud)
该代码是等待Task.Run()
,但没有内该任务正在等待LongProcess()
.所以Task.Run()
在这种情况下立即返回.
这实际上是未能"一直向下异步"的有趣例证,因为内联函数实质上隐藏了它是异步的事实.事实上,编译器应该警告你没有任何东西在等待LongProcess()
它会立即返回.
与此形成对比:
await Task.Run(async () => await LongProcess());
Run Code Online (Sandbox Code Playgroud)
编辑:我刚才注意到为什么编译器可能没有警告你.因为这:
async void
Run Code Online (Sandbox Code Playgroud)
从来没有做过这样的事情:)(好吧,有一个合理的理由要做到这一点.而且我确信它至少困扰着C#团队,他们不得不支持它只是出于这个原因.但除非你遇到一个原因,不要这样做.)
始终返回Task
异步方法,以便可以等待该方法.
归档时间: |
|
查看次数: |
848 次 |
最近记录: |