ठीक है, इसलिए मैंने एक स्थिर एसिंक्रोनस विधि बनाई। उस नियंत्रण को निष्क्रिय कर दिया जो कार्रवाई शुरू करता है और एप्लिकेशन कर्सर को बदलता है। यह कार्य को एक कार्य के रूप में चलाता है और समाप्त होने का इंतजार करता है। प्रतीक्षा करते समय कॉल करने वाले पर नियंत्रण रखें। तो अनुप्रयोग संवेदनशील रहता है, भले ही व्यस्त आइकन घूमता है।
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 का उपयोग कर रहा हूं) के लिए एक अलग लकड़हारे का उपयोग करना पड़ा और मेरा मुख्य लकड़हारा UI (एक समृद्ध पाठ बॉक्स) को लिख रहा है। मैं व्यस्त कर्सर को केवल तब प्राप्त नहीं कर पा रहा था जब किसी विशेष कंटेनर को फ़ॉर्म पर दिखाया गया था (लेकिन मैंने बहुत कोशिश नहीं की थी।) सभी नियंत्रणों में एक 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