OK così ho creato un metodo asincrono statico. Che disabilita il controllo che avvia l'azione e modifica il cursore dell'applicazione. Esegue l'azione come compito e attende di finire. Il controllo ritorna al chiamante mentre attende. Quindi l'applicazione rimane reattiva, anche mentre l'icona occupata ruota.
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;
}
Ecco il modulo di codice del modulo principale
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
{
}
}
ho dovuto usare un registratore separato per l'azione fittizio (sto usando nlog) e il mio logger principale sta scrivendo l'interfaccia utente (una ricca casella di testo). Non è stato possibile visualizzare lo stato occupato del cursore solo quando si trovava su un determinato contenitore del modulo (ma non ci ho provato molto duramente.) Tutti i controlli hanno una proprietà UseWaitCursor, ma non sembra avere alcun effetto sui controlli ho provato (forse perché non erano in cima?)
Ecco il registro principale, che mostra cose che accadono in ordine ci aspettiamo:
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
fonte
2016-08-04 01:06:07
non è necessario modificare il cursore, se il ciclo del messaggio non verrà chiamato durante il codice che richiede molto tempo. per abilitarlo è necessario aggiungere _Application.DoEvents(); _ dopo il primo set di cursori. – Amirshk
Probabilmente vorrai provare..finalmente bloccare dopo aver impostato anche Current (assicurandoti che Current venga ripristinato al valore predefinito). – TrueWill
FYI, non ho potuto ottenere quanto sopra per funzionare, ma cambiandolo in this.cursor = cursors.waitcursor; ha funzionato. –