私の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 をクリックすると、Wait カーソルが表示されます (作業が非同期で行われるため)。
- button2 をクリックしても、待機カーソルは表示されません(作業はすべて同期的に行われるため)。
- button1 と button2 のいずれかをクリックすると、期待どおりに UI が無効になります。
望ましいのは、button1 または button2 のいずれかをクリックすると、ボタンをクリックしてから UI 更新作業が完了するまでの間、Wait カーソルが表示されるようにすることです。
質問:
- を挿入せずにこれを解決する方法はあり
Application.DoEvent
ますか (または、メッセージのポンピングを発生させる同等のものはありません)、またはメッセージをポンピングすることによってのみ可能です。 - 余談ですが、コントロールの無効化が正しく機能するのはなぜですか(カーソルとは異なります)。