c#Best Practice winforms async / await keywords

时间:2017-06-14 10:02:00

标签: 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
        } 

但我想知道这是否是使用async和等待关键字的最佳做法,我感到有点不舒服&#34;操纵&#34; button1_click事件的签名

3 个答案:

答案 0 :(得分:3)

在Windows窗体上使用async事件处理程序是正确的,建议的方法。如果不使用async await,则可能会看到死锁(除非您使用的是ConfigureAwait(false))。

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

重要的是,将所有逻辑保持在单独的方法中以使单元可测试。测试异步无效是很困难的。您无法将方法更改为异步任务

// 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);

在下面提到的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");
}

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

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

答案 1 :(得分:0)

There is another approach to achieve this.

Parallel.foreach("list",(currentelement) => {

enter code here

}); Basically this will work as async.

答案 2 :(得分:-1)

我在登录解决方案中实现了这一点。你可以这样做。

 private async void metroButton1_Click(object sender, EventArgs e)
    {
        string res= await login();
        if (res.Equals("true"))
        {
            this.Hide();
            MainMDIParent mdi = new MainMDIParent();
            mdi.Show();
            btnLogin.Enabled = true;
        }
        else
        {

            MessageBox.Show("Invalid User Credentials", "LOgin", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            txtPassword.Text = "";
            txtUsername.Text = "";
            btnLogin.Enabled = true;

        }

    }