OK jadi saya membuat metode async statis. Itu menonaktifkan kontrol yang meluncurkan aksi dan mengubah kursor aplikasi. Itu menjalankan tindakan sebagai tugas dan menunggu untuk selesai. Kontrol kembali ke pemanggil saat menunggu. Jadi aplikasi tetap responsif, bahkan saat ikon sibuk berputar.
async public static void LengthyOperation(Control control, Action action)
{
try
{
control.Enabled = false;
Application.UseWaitCursor = true;
Task doWork = new Task(() => action(), TaskCreationOptions.LongRunning);
Log.Info("Task Start");
doWork.Start();
Log.Info("Before Await");
await doWork;
Log.Info("After await");
}
finally
{
Log.Info("Finally");
Application.UseWaitCursor = false;
control.Enabled = true;
}
Berikut kode dari form utama
private void btnSleep_Click(object sender, EventArgs e)
{
var control = sender as Control;
if (control != null)
{
Log.Info("Launching lengthy operation...");
CursorWait.LengthyOperation(control, () => DummyAction());
Log.Info("...Lengthy operation launched.");
}
}
private void DummyAction()
{
try
{
var _log = NLog.LogManager.GetLogger("TmpLogger");
_log.Info("Action - Sleep");
TimeSpan sleep = new TimeSpan(0, 0, 16);
Thread.Sleep(sleep);
_log.Info("Action - Wakeup");
}
finally
{
}
}
Saya harus menggunakan logger terpisah untuk aksi dummy (saya menggunakan Nlog) dan logger utama saya menulis ke UI (kotak teks kaya). Saya tidak bisa mendapatkan tampilan kursor yang sibuk hanya ketika melewati wadah tertentu pada formulir (tapi saya tidak berusaha sangat keras). Semua kontrol memiliki properti UseWaitCursor, tetapi tampaknya tidak berpengaruh pada kontrol Saya mencoba (mungkin karena mereka tidak di atas?)
Inilah log utama, yang menunjukkan hal-hal yang terjadi dalam urutan yang kami harapkan:
16:51:33.1064 Launching lengthy operation...
16:51:33.1215 Task Start
16:51:33.1215 Before Await
16:51:33.1215 ...Lengthy operation launched.
16:51:49.1276 After await
16:51:49.1537 Finally