c# - 使用 async await 仍然会卡住 GUI

标签 c# user-interface asynchronous 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 秒后显示完成!它才会变得无响应)。我做错了什么?

编辑: 我正在尝试替换以下逻辑:

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 替换它并不能解决任何问题。此外,我不明白为什么你应该使用另一个 sleep 命令? async/await 设计对此有何要求?

最佳答案

您可以使用 Task.RunTask.Factory.StartNew 来执行 Test() 或一些长时间运行和/或阻塞的操作在另一个线程上:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await Task.Run(() => Test());
    txtResult.Text = "Done!";
}

关于c# - 使用 async await 仍然会卡住 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35724024/

相关文章:

java - 使用按钮删除 EditText 中的文本

java - 如何排列Java GUI按钮?

c# - 如何更改 RSACryptoServiceProvider 的 CSP 参数

c# - ConfigurationManager.ConnectionStrings 从 machine.config 返回额外的连接字符串

C# WPF 程序在调试中运行,但不调试就无法发布

c# - Windows 上的优质 Mono/ASP.NET 开发环境?

iphone - 自定义 NavigationBar 按钮在 iOS 7 中看起来不同

asynchronous - 是否有必要在异步 redis 客户端中使用池

javascript - 异步获取数据,将结果聚合到一个对象。默认情况下,对象是否被 javascript 锁定?

c# - 将一个方法变成可等待的