C# 如何使窗体事件利用异步的优点?

C# 如何使窗体事件利用异步的优点?,c#,winforms,C#,Winforms,我有一个简单的buton和一个事件按钮1\u点击: public Form1 : Form { public Form1() { ... this.button1.Click += new System.EventHandler(this.button1_Click); } private async Task button1_Click(object sender, EventArgs e) // line A {

我有一个简单的buton和一个事件按钮1\u点击:

public Form1 : Form
{
    public Form1()
    {
        ...
        this.button1.Click += new System.EventHandler(this.button1_Click);
    }

    private async Task button1_Click(object sender, EventArgs e) // line A
    {
    }
}

在A行中,我想尝试使用异步任务返回类型,而不是void,我遇到了来自编译器的错误消息。如何运行此代码?

事件处理程序是返回类型为
void
的委托,这意味着您不能向其添加带有
Task
result的方法


但是,您也可以将
void
方法标记为
async
,因此您只需将
Task
替换为
void

,事件处理程序是返回类型为
void
的委托,这意味着您不能向其添加带有
Task
结果的方法

但是,您也可以将
void
方法标记为
async
,因此您只需将
任务
替换为
void

我怎样才能使这段代码运行

无法执行此操作,因为未为.net中的UI事件处理程序实现
异步任务
签名。(请务必阅读此帖子:)

一般的共识是,一般来说,事件处理程序的返回值没有明确定义的用途。虽然在我看来,能够异步启动所有处理程序是有意义的,但是,如果您不等待其中的逻辑,情况也会如此

当然,您可以通过将事件逻辑放在另一个类中来克服这个问题。不管怎样,大多数时候这实际上是个好主意

注意:不要这样使用它,它只是为了解释它 另见:


如何使窗体事件利用异步的优点

所以,基本上它已经做到了,但是看看这篇文章:

我怎样才能使这段代码运行

无法执行此操作,因为未为.net中的UI事件处理程序实现
异步任务
签名。(请务必阅读此帖子:)

一般的共识是,一般来说,事件处理程序的返回值没有明确定义的用途。虽然在我看来,能够异步启动所有处理程序是有意义的,但是,如果您不等待其中的逻辑,情况也会如此

当然,您可以通过将事件逻辑放在另一个类中来克服这个问题。不管怎样,大多数时候这实际上是个好主意

注意:不要这样使用它,它只是为了解释它 另见:


如何使窗体事件利用异步的优点

所以,基本上它已经做到了,但是看看这篇文章:
我们可以检查以下代码:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.button1.Click += (s, e) => Button1_Click(s, e);
        //this.button1.Click += Button1_Click1;
        MessageBox.Show("The End!");
    }
    private async Task Button1_Click(object sender, EventArgs e)
    {
        await Task.Delay(5000);
        MessageBox.Show("With Sync");
    }

    private void Button1_Click1(object sender, EventArgs e)
    {
        MessageBox.Show("Without async");
    }
}

我们可以检查以下代码:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        this.button1.Click += (s, e) => Button1_Click(s, e);
        //this.button1.Click += Button1_Click1;
        MessageBox.Show("The End!");
    }
    private async Task Button1_Click(object sender, EventArgs e)
    {
        await Task.Delay(5000);
        MessageBox.Show("With Sync");
    }

    private void Button1_Click1(object sender, EventArgs e)
    {
        MessageBox.Show("Without async");
    }
}

我认为下面的建议很好,很实用。但是,在DevExpress设计模式中有时会出现中断。因此,我将我的解决方案放在进一步讨论中:

public Form1 : Form
{
    public Form1()
    {
        ...
        this.button1.Click += 
             new System.EventHandler(
                 async (sender, events) => await this.button1_Click(sender, events)
             );
    }

    private async Task button1_Click(object sender, EventArgs e) // line A
    {
    }
}

我认为下面的建议很好,很实用。但是,在DevExpress设计模式中有时会出现中断。因此,我将我的解决方案放在进一步讨论中:

public Form1 : Form
{
    public Form1()
    {
        ...
        this.button1.Click += 
             new System.EventHandler(
                 async (sender, events) => await this.button1_Click(sender, events)
             );
    }

    private async Task button1_Click(object sender, EventArgs e) // line A
    {
    }
}

您可以在事件处理程序中使用
asyns void
。您可以在事件处理程序中使用
asyns void
。异步void是一种糟糕的做法。在多线程编程中,它有一个流程。请阅读async with void的情况,您没有机会在void事件处理程序中使用其他任何东西,而在wpf和winforms中,您只有这些。如果您不知道自己在做什么以及应该如何使用它,这可能会很危险,但对于其他任何事情也是如此。async void是一种糟糕的做法。在多线程编程中,它有一个流程。请阅读async with void的情况,您没有机会在void事件处理程序中使用其他任何东西,而在wpf和winforms中,您只有这些。如果你不知道自己在做什么以及应该如何使用它,这可能是危险的,但对于其他任何事情也是如此。Wait是否会使这个不和谐的调用同步?Async保证您的逻辑将完成,但一旦调用该方法,您只需等待逻辑完成。这是一个有点技巧的问题。简而言之:
await
所做的是,它异步执行代码(因此您的ui保持响应),但随后会从该点恢复。这就像把你的函数分成两部分。wait是否会使这个非同步调用同步?Async保证您的逻辑将完成,但一旦调用该方法,您只需等待逻辑完成。这是一个有点技巧的问题。简而言之:
await
所做的是,它异步执行代码(因此您的ui保持响应),但随后会从该点恢复。这就像把你的函数分成两部分。这只是掩盖了一个事实,即事件处理程序是一个匿名方法,返回无效。您仍然可以更方便地处理无效事件。事实上,这要糟糕得多,因为它的行为相同,但很容易误导读者认为这不是一个fire-and-forget操作,而实际上是。这只是掩盖了一个事实,即事件处理程序是无效的,通过将其设置为匿名方法返回。您仍然可以更方便地处理无效事件。事实上,这要糟糕得多,因为它的行为相同,但很容易误导读者,让他们认为这不是一个“失火即忘”的操作,而实际上是这样。