के भीतर सिंक्रोनस I/O मान लें कि मेरे पास एक विंडोज सेवा है जो कुछ काम कर रही है, फिर थोड़ी देर के लिए सो रही है, हमेशा के लिए और अधिक (जब तक सेवा बंद नहीं होती नीचे)।एक एसिंक/प्रतीक्षा-आधारित विंडोज सेवा
private void WorkerThreadFunc()
{
while (!shuttingDown)
{
DoSomething();
Thread.Sleep(10);
}
}
और सेवा के OnStop में, मैं किसी भी तरह कि ShuttingDown ध्वज सेट और फिर धागा शामिल हो: तो सेवा के onStart में, मैं एक धागा जिसका प्रवेश बिंदु है की तरह कुछ शुरू कर सकता है। असल में ऐसे कई धागे और अन्य धागे भी हो सकते हैं, सभी ऑनस्टार्ट में शुरू हो गए और ऑनस्टॉप में बंद/शामिल हो गए।
यदि मैं इस तरह की चीज को एसिंक/प्रतीक्षा विंडोज आधारित सेवा में करना चाहता हूं, तो ऐसा लगता है कि मैं ऑनस्टार्ट को रद्द करने योग्य कार्यों को बना सकता हूं लेकिन उन पर प्रतीक्षा नहीं कर रहा हूं (या प्रतीक्षा करें), और ऑनस्टॉप उन कार्यों को रद्द कर दें और फिर कार्य करें। जब सभी()। उन पर प्रतीक्षा करें()।
private async Task WorkAsync(CancellationToken cancel)
{
while (true)
{
cancel.ThrowIfCancellationRequested();
DoSomething();
await Task.Delay(10, cancel).ConfigureAwait(false);
}
}
प्रश्न # 1: अगर मैं सही ढंग से समझ, "WorkerThreadFunc" ऊपर दिखाए गए के बराबर की तरह कुछ हो सकता है उह ... है ना? मैं async/प्रतीक्षा करने के लिए नया हूं और अभी भी इसके चारों ओर अपना सिर लेने की कोशिश कर रहा हूं।
मान लीजिए कि यह सही है, अब मान लें कि DoSomething() कॉल हार्डवेयर के कुछ हिस्सों में एक तुल्यकालिक लेखन I/O है (या शामिल है)। अगर मैं सही ढंग से समझ रहा हूं:
प्रश्न # 2: यह बुरा है? मुझे एक async/प्रतीक्षा-आधारित प्रोग्राम में एक कार्य के भीतर तुल्यकालिक I/O नहीं करना चाहिए? चूंकि यह थ्रेड पूल से धागे से जुड़ा हुआ है, जबकि I/O हो रहा है, और थ्रेड पूल से धागे अत्यधिक सीमित संसाधन हैं? कृपया ध्यान दें कि मेरे पास दर्जनों ऐसे श्रमिक हार्डवेयर के विभिन्न टुकड़ों के साथ-साथ जा रहे हैं।
मुझे यकीन नहीं है कि मैं इसे सही ढंग से समझ रहा हूं - मुझे यह विचार मिल रहा है कि स्टीफन क्लेरी के "Task.Run Etiquette Examples: Don't Use Task.Run for the Wrong Thing" जैसे लेखों से यह बुरा है, लेकिन यह विशेष रूप से टास्क के अंदर काम को अवरुद्ध करने में बुरा होने के बारे में है। मुझे यकीन नहीं है कि अगर मैं इसे सीधे कर रहा हूं, तो यह भी बुरा है, जैसा ऊपर "निजी एसिंक कार्य कार्य()" उदाहरण में है?
यह मानते हुए कि बहुत बुरा है, तो अगर मैं सही ढंग से समझ मैं बजाय nonblocking (इसके बारे में एक nonblocking संस्करण बनाने अगर यह पहले से ही मौजूद नहीं है) DoSomething के संस्करण का उपयोग करना चाहिए, और उसके बाद:
private async Task WorkAsync(CancellationToken cancel)
{
while (true)
{
cancel.ThrowIfCancellationRequested();
await DoSomethingAsync(cancel).ConfigureAwait(false);
await Task.Delay(10, cancel).ConfigureAwait(false);
}
}
प्रश्न # 3: लेकिन ... क्या होगा यदि किसी तीसरे पक्ष की लाइब्रेरी से कुछ करना है, जिसे मुझे उपयोग करना चाहिए और बदल नहीं सकता है, और वह लाइब्रेरी DoSomething के एक गैर-ब्लॉकिंग संस्करण का पर्दाफाश नहीं करती है? यह पत्थर में बस एक काला बॉक्स सेट है जो किसी बिंदु पर हार्डवेयर के एक टुकड़े को अवरुद्ध करता है।
शायद मैं इसे लपेटूं और कार्यसंचार स्रोत का उपयोग करें? कुछ ऐसा:
private async Task WorkAsync(CancellationToken cancel)
{
while (true)
{
cancel.ThrowIfCancellationRequested();
await WrappedDoSomething().ConfigureAwait(false);
await Task.Delay(10, cancel).ConfigureAwait(false);
}
}
private Task WrappedDoSomething()
{
var tcs = new TaskCompletionSource<object>();
DoSomething();
tcs.SetResult(null);
return tcs.Task;
}
लेकिन ऐसा लगता है कि यह इस मुद्दे को हल करने के बजाए थोड़ा और आगे दबा रहा है। WorkAsync() अभी भी अवरुद्ध होगा जब इसे लपेटा गया कुछ(), और केवल इसके लिए "प्रतीक्षा" प्राप्त करें, इसके बाद लपेटा हुआ कुछ() पहले ही ब्लॉकिंग कार्य पूरा कर चुका है। सही?
सामान्य मामले में (यदि मैं सही ढंग से समझता हूं) को देखते हुए एसिंक/प्रतीक्षा को प्रोग्राम में ऊपर और नीचे "फैलाने" की अनुमति दी जानी चाहिए, तो इसका मतलब यह होगा कि अगर मुझे ऐसी लाइब्रेरी का उपयोग करने की ज़रूरत है, तो मैं इसका मतलब दूंगा अनिवार्य रूप से कार्यक्रम async/प्रतीक्षा-आधारित नहीं करना चाहिए? मुझे थ्रेड/वर्कर थ्रेडफनक/थ्रेड पर वापस जाना चाहिए। नींद की दुनिया?
क्या होगा यदि एक async/await- आधारित प्रोग्राम पहले से मौजूद है, अन्य चीजें कर रहा है, लेकिन अब ऐसी लाइब्रेरी का उपयोग करने वाली अतिरिक्त कार्यक्षमता को इसमें जोड़ा जाना चाहिए? क्या इसका मतलब यह है कि एसिंक/प्रतीक्षा-आधारित कार्यक्रम को थ्रेड/इत्यादि-आधारित प्रोग्राम के रूप में फिर से लिखा जाना चाहिए?
यह एक बहुत ही समझदार उत्तर है। कारण यह नहीं है कि सब कुछ एसिंक है या नहीं होना चाहिए कि async डेवलपर के लिए काम करता है और कोड की प्रति इकाई की बग की दर बढ़ाता है। यह मुख्य काउंटर प्वाइंट है। यदि आप एसिंक जाते हैं तो एक ठोस लाभ होना चाहिए। – usr