使用async/await时防止winforms UI阻止

Ben*_*nji 5 c# asynchronous winforms 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;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我通过在Task.Run中包装"DoStuffAsync()"的主体进行轻微更改时,它的工作完全正常

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;
    }
Run Code Online (Sandbox Code Playgroud)

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

Rez*_*aei 11

当你写这样的代码时:

private async Task<int> DoStuffAsync()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以同步处理,因为你没有使用await表达式.

注意警告:

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

根据警告建议,您可以这样纠正:

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

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