如何在WinForms按钮单击事件中调用异步方法?

13

我有一个I/O绑定的方法,我希望异步运行。

帮助文档中提到,我应该在不使用Task.Run的情况下使用async和await

引用如下:

对于I/O绑定的代码,您可以在async方法内等待返回Task或Task的操作。

我如何从winforms按钮单击事件中做到这一点?

我已经尝试过了

private void button_Click(object sender, EventArgs e)
{ 
      await doLoadJob();
}

private async Task<int> doLoadJob()
{
    await loadJob();   
    return 0;
}

5
private async void button_Click(object sender, EventArgs e) - JohanP
看起来 loadJob() 是一个同步方法,而不是异步方法,所以你收到的警告已经有了答案:“或者使用 'await Task.Run(...)' 在后台线程上执行 CPU 绑定的工作”。因此,在你的处理程序中使用 await Task.Run(() => loadJob())(以及像其他人建议的那样使处理程序异步)。如果可能的话最好将 loadJob() 改为异步,但只要它保持同步,你就需要这样做。 - sellotape
@KirstenGreed - 你已经修改了问题,以至于一个连贯的答案是不可能的。关于你最新的编辑,I/O绑定代码并不是神奇的异步;相反,它通常非常适合被制作成异步。loadJob()似乎是同步的,无论其活动的性质如何。只要它是同步的,你就必须使用Task.Run()来实现你想要的效果。你刚刚添加的引用说:“对于I/O绑定的代码,你在异步方法内等待返回Task或Task的操作”- loadJob()是否返回一个Task - sellotape
@sellotape 对于我的编辑我很抱歉,它们都是为了表达我的问题,但问题并没有改变。LoadJob返回void。 - Kirsten
@KirstenGreed - 假设无法将其变为异步(“源代码不可用”),则需要使用 Task.Run(),否则处理程序将会阻塞。 - sellotape
显示剩余5条评论
1个回答

19

你的 button_Click 方法需要改为 async。在 privatevoid 之间添加一个 async

private async void button_Click(object sender, EventArgs e)
{ 
     await LongOperation();
}

@KirstenGreed 那可能是一个“新问题”。Joao是正确的。你的LongOperation代码是否真正异步还有待确定。 - user585968
你无法移动窗体,因为 System.Threading.Thread.Sleep 影响了你的主线程(应用程序线程)。 - RamblinRose
有什么建议可以模拟IO绑定事件吗? - Kirsten
3
请将"@KirstenGreed post that into a new question. Stop changing the scope of your original question. Your original post shows no such code"翻译成中文。请将其转述为新问题。请勿改变原问题的范围。您最初的帖子中没有显示此类代码。 - user585968
因为您错误地描述了问题,它解决了您提出的问题。请接受这一点,提出一个新问题,并可能花费更多时间提供相关示例。请注意,您的代码示例中没有睡眠,因此它不会引起问题。您所提出的问题已经得到了回答。 - TomTom
4
抱歉,我尝试提出一个新问题,但它被投票关闭为重复问题。 - Kirsten

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接