在我的Winforms应用程序中,当您启动操作时,它可能会也可能不会异步完成。如果工作全部同步完成,我无法使用我异步完成工作时使用的相同方法显示等待光标。
以下是显示问题的示例:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var t = ButtonClick(button1, DoWorkAsync1);
}
private void button2_Click(object sender, EventArgs e)
{
var t = ButtonClick(button2, DoWorkAsync2);
}
private async Task ButtonClick(Button btn, Func<Task> doWorkAsync)
{
// Disable the UI and show the wait cursor
btn.Text = "Working...";
btn.Enabled = false;
UseWaitCursor = true;
// Application.DoEvents(); // Inserting this causes the problem to go away.
await doWorkAsync();
// Simulate an update of the UI taking a long time
Thread.Sleep(2000);
// Renable the UI and stop showing the wait cursor
UseWaitCursor = false;
btn.Enabled = true;
}
private Task DoWorkAsync1()
{
// Work takes some time
return Task.Delay(2000);
}
private Task DoWorkAsync2()
{
// Work doesn't take any time, results are immediately available
return Task.FromResult<int>(0);
}
}
在这个例子中:
所需要的是单击button1或button2会导致在单击按钮和UI更新工作完成之间的整个时间间隔内显示等待光标。
问题:
Application.DoEvent
的情况下解决这个问题(也没有任何可能导致消息发生的等效事项),或者只能通过抽取消息来解决这个问题。答案 0 :(得分:0)
如果您要在后台线程上进行同步工作,请在Task.Run
中调用它,然后await
调用结果(调用代码将其视为异步)。
private Task DoWorkAsync1()
{
return Task.Delay(2000);
}
private Task DoWorkAsync2()
{
return Task.Run(() => Thread.Sleep(2000));
}
或者,如果您的同步工作确实是即时的,并且您真的想在其他UI工作之前应用一些UI更新(例如光标),那么您可以简单地执行此操作:
await Task.Delay(10);
答案 1 :(得分:0)
而不是DoEvents
投入:
await Task.Run(() => { });
这将确保等待任务在启动时没有完成,因此方法的其余部分将作为延续而不是同步运行。
或者,您可以直接向doWorkAsync
添加延迟,确保不会同步运行:
await doWorkAsync
.ContinueWith(t => { }, TaskContinuationOptions.HideScheduler);