c# 最佳实践 winforms async/await 关键字

0 c# asynchronous

测试一下 TPL。

我使用此代码并且它有效

async void button1_Click(object sender, EventArgs e)
        {

            MyClass2 mc2 = new MyClass2();
            label1.Text = "Start";
            List<string> list = await mc2.GetInfosAsync("test123");
            label1.Text = "";
            list.ForEach(x => label1.Text += x + "\n");
        }
    }
    class MyClass2
    {
        public Task<List<string>> GetInfosAsync(string txt)
        {
            return Task.Factory.StartNew<List<string>>(() => GetInfos(txt));
        }

        public List<string> GetInfos(string txt)
        { 
            //doing long-listbuilding-operation
        } 
Run Code Online (Sandbox Code Playgroud)

但我想知道这是否是使用 async 和 await 关键字的最佳实践,“操纵”button1_click事件的签名让我感到有点不舒服

Kau*_*hal 5

在 Windows 窗体事件处理程序上使用 async 是正确且推荐的方法。如果您不使用异步等待,您可能会看到死锁(除非您使用的是 ConfigureAwait(false))。

在您的代码中一直使用 async await 。不要使用 Wait() 或 Result

一件重要的事情,将所有逻辑保持在单独的方法中以使单元可测试。测试 async void 会很困难。您不能将方法更改为异步任务

// Will result in compilation error 
private async Task button1_Click(object sender, EventArgs e) 

// Because of event handler signature
public delegate void EventHandler(object sender, EventArgs e);
Run Code Online (Sandbox Code Playgroud)

下面提到的 msdn 文章中提到了一个很好的例子来处理这个问题

public async void button1_Click(object sender, EventArgs e)
{
  await this.ButtonClickHandlerAsync()
}    

// Unit test this
public async Task ButtonClickHandlerAsync()
{
        MyClass2 mc2 = new MyClass2();
        label1.Text = "Start";
        List<string> list = await mc2.GetInfosAsync("test123");
        label1.Text = "";
        list.ForEach(x => label1.Text += x + "\n");
}
Run Code Online (Sandbox Code Playgroud)

更多详情 - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

PS:我假设您的问题是关于“在 winform 按钮单击事件处理程序上使用异步的好习惯”?从技术上讲,异步不是方法签名的一部分(只有方法名称和参数)。如果您的问题实际上是关于签名的,请忽略此答案。