使用异步/等待时防止Winforms UI阻止 [英] Prevent winforms UI block when using async/await

查看:58
本文介绍了使用异步/等待时防止Winforms UI阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对异步/等待编程还很陌生,有时我觉得自己理解了,然后突然发生了一些事情,使我陷入了循环.

I'm fairly new to async/await programming and sometimes I feel that I understand it, and then all of a sudden something happens and throws me for a loop.

我正在测试Winforms应用程序中尝试此操作,这是我拥有的代码段的一个版本.这样做会阻塞用户界面

I'm trying this out in a test winforms app and here is one version of a snippet that I have. Doing it this way will block the 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中进行细微更改时,运行它就可以了.

Now, when I make a slight change by wrapping the body of "DoStuffAsync()" in a Task.Run it works perfectly fine

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;
    }

话虽如此,处理这种情况的正确方法是什么?

With all that said, what is the proper way to handle this scenario?

推荐答案

编写此类代码时:

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

通过这种方式,您可以同步处理事务,因为您没有使用await表达式.

This way you are doing things synchronously, because you are not using await expression.

请注意警告:

此异步方法缺少等待"运算符,将同步运行. 考虑使用"await"运算符来等待非阻塞API调用, 或"await Task.Run(...)"在后台线程上执行CPU绑定的工作.

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.

根据警告建议,您可以通过以下方式进行纠正:

Based on the warning suggestion you can correct it this way:

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

要了解有关异步/等待的更多信息,请查看:

To learn more about async/await you can take a look at:

  • Async and Await by Stephen Cleary
  • Asynchronous Programming with Async and Await from msdn

这篇关于使用异步/等待时防止Winforms UI阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆