कभी-कभी घटना होने की प्रतीक्षा करते समय यह मेरे धागे को अवरुद्ध करना चाहता है।किसी ईवेंट के लिए अवरुद्ध और प्रतीक्षा
मैं आमतौर पर यह कुछ इस तरह करते हैं:
private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private void OnEvent(object sender, EventArgs e){
_autoResetEvent.Set();
}
// ...
button.Click += OnEvent;
try{
_autoResetEvent.WaitOne();
}
finally{
button.Click -= OnEvent;
}
हालांकि, ऐसा लगता है कि यह कुछ है कि मैं (या शायद यह भी कुछ है जो पहले से ही ढांचे में मौजूद है) एक आम वर्ग के लिए निकाल सकते होना चाहिए।
मैं इस तरह कुछ करने के लिए सक्षम होने के लिए करना चाहते हैं:
EventWaiter ew = new EventWaiter(button.Click);
ew.WaitOne();
EventWaiter ew2 = new EventWaiter(form.Closing);
ew2.WaitOne();
लेकिन मैं वास्तव में (जैसे कि एक वर्ग के निर्माण के लिए एक तरह से मैं पारित करने के लिए एक अच्छा वैध रास्ता नहीं मिल सकता है नहीं मिल सकता है एक तर्क के रूप में घटना)। क्या कोई मदद कर सकता है?
var status = ShowStatusForm();
status.ShowInsertUsbStick();
bool cancelled = WaitForUsbStickOrCancel();
if(!cancelled){
status.ShowWritingOnUsbStick();
WriteOnUsbStick();
status.AskUserToRemoveUsbStick();
WaitForUsbStickToBeRemoved();
status.ShowFinished();
}else{
status.ShowCancelled();
}
status.WaitUntilUserPressesDone();
यह बहुत अधिक संक्षिप्त और तर्क कई तरीकों के बीच फैला के साथ लिखा बराबर कोड से पढ़ी जा सकती है:
क्यों यह उपयोगी हो सकता है का एक उदाहरण देने के लिए, कुछ इस तरह विचार करें। लेकिन WaitForUsbStickOrCancel() को लागू करने के लिए, WaitForUsbStickToBeRemoved और WaitUntilUserPressesDone() (मान लीजिए कि जब हमें यूएसबी स्टिक डाली जाती है या निकाल दिया जाता है तो हमें एक ईवेंट मिलता है) मुझे हर बार "EventWaiter" को फिर से लागू करने की आवश्यकता होती है। बेशक आपको जीयूआई-थ्रेड पर इसे चलाने के लिए सावधान रहना होगा, लेकिन कभी-कभी यह सरल कोड के लिए एक सार्थक ट्रेडऑफ है।
विकल्प कुछ इस तरह दिखेगा:
var status = ShowStatusForm();
status.ShowInsertUsbStick();
usbHandler.Inserted += OnInserted;
status.Cancel += OnCancel;
//...
void OnInserted(/*..*/){
usbHandler.Inserted -= OnInserted;
status.ShowWritingOnUsbStick();
MethodInvoker mi =() => WriteOnUsbStick();
mi.BeginInvoke(WritingDone, null);
}
void WritingDone(/*..*/){
/* EndInvoke */
status.AskUserToRemoveUsbStick();
usbHandler.Removed += OnRemoved;
}
void OnRemoved(/*..*/){
usbHandler.Removed -= OnRemoved;
status.ShowFinished();
status.Done += OnDone;
}
/* etc */
मुझे लगता है कि बहुत कठिन पढ़ने के लिए लगता है। माना जाता है कि यह हमेशा से दूर है कि प्रवाह इतना रैखिक होगा, लेकिन जब यह है, मुझे पहली शैली पसंद है।
यह ShowMessage() और Form.ShowDialog() का उपयोग करने के लिए तुलनीय है - वे कुछ "ईवेंट" होने तक भी अवरुद्ध होते हैं (हालांकि वे एक संदेश-लूप चलाएंगे यदि उन्हें गुई-थ्रेड पर बुलाया जाता है)।
क्यों वास्तव में आप ऐसा करना चाहते हैं चाहते हैं मैं उत्सुक हूँ ... आप विस्तार से बता सकते हैं? –
मुझे अभी भी समझ में नहीं आ रहा है कि आप घटना के इंतजार के बजाय धागे को अवरुद्ध क्यों करना चाहते हैं - यह क्या करता है? –
क्या आपने कभी इसे ठीक किया है? मुझे भी यही तकलीफ़ है। – Carlo