C# 如何使窗体事件利用异步的优点?
我有一个简单的buton和一个事件按钮1\u点击: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 {
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操作,而实际上是。这只是掩盖了一个事实,即事件处理程序是无效的,通过将其设置为匿名方法返回。您仍然可以更方便地处理无效事件。事实上,这要糟糕得多,因为它的行为相同,但很容易误导读者,让他们认为这不是一个“失火即忘”的操作,而实际上是这样。