c# - 使用 async/await 时防止 winforms UI 阻塞

标签 c# winforms asynchronous async-await

我对 async/await 编程还很陌生,有时我觉得我理解它,然后突然间发生了一些事情,让我陷入了困境。

我正在测试 winforms 应用程序中进行尝试,这是我拥有的一个片段版本。这样做会阻塞 UI

private async void button1_Click(object sender, EventArgs e)
{

    int d = await DoStuffAsync(c);

    Console.WriteLine(d);

}

private async Task<int> DoStuffAsync(CancellationTokenSource c)
{

        int ret = 0;

        // I wanted to simulator a long running process this way
        // instead of doing Task.Delay

        for (int i = 0; i < 500000000; i++)
        {



            ret += i;
            if (i % 100000 == 0)
                Console.WriteLine(i); 

            if (c.IsCancellationRequested)
            {
                return ret;
            }
        }
        return ret;
}

现在,当我通过将“DoStuffAsync()”的主体包装在 Task.Run 中进行轻微更改时,它工作得很好

private async Task<int> DoStuffAsync(CancellationTokenSource c)
    {
        var t = await Task.Run<int>(() =>
        {
            int ret = 0;
            for (int i = 0; i < 500000000; i++)
            {



                ret += i;
                if (i % 100000 == 0)
                    Console.WriteLine(i);

                if (c.IsCancellationRequested)
                {
                    return ret;
                }
            }
            return ret;

        });


        return t;
    }

综上所述,处理这种情况的正确方法是什么?

最佳答案

当你写这样的代码时:

private async Task<int> DoStuffAsync()
{
    return 0;
}

这样您就可以同步执行操作,因为您没有使用 await 表达式。

注意警告:

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

根据警告建议,您可以这样修改:

private async Task<int> DoStuffAsync()
{
    return await Task.Run<int>(() =>
    {
        return 0;
    });
}

要了解有关 async/await 的更多信息,您可以查看:

关于c# - 使用 async/await 时防止 winforms UI 阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33587832/

相关文章:

c# - 使用 C# 使用 crystalreportsviewer 打开表单

winforms - 获取 System.Windows.Forms.RichTextBox 的标准上下文菜单

python - 如何在 python 中一次发送一个异步 http 请求?

ios - 从 Swift 函数中的异步调用返回数据

c# - 字符串序列化和反序列化问题

c# - DataGridView 性能与 BindingList 数据源相结合

c# - 只读依赖属性更新但首次使用时不起作用

c# - 如何动态填充 TreeView (C#)

c# - 放入字节数组的德语特殊字符

javascript - 为什么这个 'feelings' 显示为一个对象,而不是我在文本字段中输入的内容?