[英]Using async await still freezes GUI
我想在單獨的線程中處理長時間運行的操作,並使用async / await模式將控制返回到GUI線程,如下所示:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Test();
txtResult.Text = "Done!";
}
private Task Test()
{
Thread.Sleep(3000);
return Task.FromResult(0);
}
問題是,它無論如何都會凍結GUI 3秒鍾(在3秒后顯示Done!之前它會變得無法響應)。 我究竟做錯了什么?
編輯:我試圖取代以下邏輯:
private void Button_Click(object sender, RoutedEventArgs e)
{
var thread = new Thread(() => Test(Callback));
thread.Start();
}
private void Callback()
{
Dispatcher.Invoke(() =>
txtResult.Text = "Done!");
}
private void Test(Action callback)
{
Thread.Sleep(3000); //long running operation, not necessarily pause
callback();
}
在實際項目中,我有不同的長時間運行邏輯而不僅僅是Sleep,它仍然會凍結GUI,因此用Task.Delay替換它並不能解決任何問題。 此外,我不明白為什么你應該使用另一個命令睡眠? async / await設計需要什么?
您可以使用Task.Run
或Task.Factory.StartNew
在另一個線程上執行Test()
或一些長時間運行和/或阻塞操作:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() => Test());
txtResult.Text = "Done!";
}
你正在使用Thread.Sleep
來阻止線程。 使用Task.Delay
,它在內部使用一個計時器,並異步地將控制權交還給調用者:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await TestAsync();
txtResult.Text = "Done!";
}
private async Task<int> TestAsync()
{
await Task.Delay(3000);
return 0;
}
當您發布新代碼時,我建議您隔離需要在日志運行過程之后運行的回調,並自己保存Dispatcher.Invoke
並使用async-await
替換它,這將使您獲得正確的同步上下文:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(Test);
CallBack();
}
private void Callback()
{
txtResult.Text = "Done!"
}
private void Test()
{
Thread.Sleep(3000); //long running operation, not necessarily pause
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.