Добре, тому я створив статичний метод асинхронізації. Це вимкнуло керування, яке запускає дію та змінює курсор програми. Він виконує дію як завдання і чекає завершення. Керування повертається до абонента, поки він чекає. Таким чином, програма залишається чуйною, навіть якщо значок зайнято.
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;
}
Ось основна форма коду
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
{
}
}
Мені довелося використовувати окремий реєстратор для дії манекена (я використовую Nlog), і мій основний реєстратор пише в інтерфейс (багате текстове поле). Я не зміг отримати показ зайнятого курсору лише тоді, коли над певним контейнером у формі (але я не дуже старався.) Усі елементи управління мають властивість UseWaitCursor, але, схоже, це не впливає на елементи управління Я спробував (може, тому, що вони не були зверху?)
Ось головний журнал, який показує, що відбувається в тому порядку, який ми очікуємо:
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