簡體   English   中英

使用async await仍會凍結GUI

[英]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.RunTask.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM