कार्य पूरा होने तक और थ्रेड सिंक्रनाइज़ेशन तक प्रतीक्षा करने के विषय पर।समांतर। फॉरएच - ग्रेसफुल रद्दीकरण
मुझे वर्तमान में एक पुनरावृत्ति है जो मैंने समानांतर में संलग्न किया है। ForEach। नीचे दिए गए उदाहरण में मैंने लूप (.NET 4.0) की सुंदर समाप्ति को सर्वोत्तम तरीके से संभालने के तरीके के बारे में टिप्पणियों में कुछ प्रश्न उठाए हैं;
private void myFunction()
{
IList<string> iListOfItems = new List<string>();
// populate iListOfItems
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = 20; // max threads
po.CancellationToken = cts.Token;
try
{
var myWcfProxy = new myWcfClientSoapClient();
if (Parallel.ForEach(iListOfItems, po, (item, loopsate) =>
{
try
{
if (_requestedToStop)
loopsate.Stop();
// long running blocking WS call, check before and after
var response = myWcfProxy.ProcessIntervalConfiguration(item);
if (_requestedToStop)
loopsate.Stop();
// perform some local processing of the response object
}
catch (Exception ex)
{
// cannot continue game over.
if (myWcfProxy.State == CommunicationState.Faulted)
{
loopsate.Stop();
throw;
}
}
// else carry on..
// raise some events and other actions that could all risk an unhanded error.
}
).IsCompleted)
{
RaiseAllItemsCompleteEvent();
}
}
catch (Exception ex)
{
// if an unhandled error is raised within one of the Parallel.ForEach threads, do all threads in the
// ForEach abort? or run to completion? Is loopsate.Stop (or equivalent) called as soon as the framework raises an Exception?
// Do I need to call cts.Cancel here?
// I want to wait for all the threads to terminate before I continue at this point. Howe do we achieve that?
// do i need to call cts.Dispose() ?
MessageBox.Show(Logging.FormatException(ex));
}
finally
{
if (myWcfProxy != null)
{
// possible race condition with the for-each threads here unless we wait for them to terminate.
if (myWcfProxy.State == System.ServiceModel.CommunicationState.Faulted)
myWcfProxy.Abort();
myWcfProxy.Close();
}
// possible race condition with the for-each threads here unless we wait for them to terminate.
_requestedToStop = false;
}
}
किसी भी मदद की सराहना की जाएगी। मैनुअल रीसेट इवेंटस्लिम और रद्दीकरण के एमएसडीएन दस्तावेज वार्ता। टोकनहैंडल। लेकिन यह सुनिश्चित नहीं है कि इन्हें कैसे तारित किया जाए, एमएसडीएन उदाहरणों को समझने में संघर्ष कर रहे हैं क्योंकि अधिकांश लागू नहीं होते हैं।
अंतर्दृष्टि के लिए धन्यवाद। मुझे यह कहना चाहिए कि उस बिंदु पर जहां आप सही तरीके से "अन्य सभी अपवादों को निगलते हैं" इंगित करते हैं, मैं एक लॉगिंग कॉल कर रहा हूं जो वेब सेवा या क्लाइंट साइड डब्ल्यूसीएफ अपवाद लॉग करेगा। अगर अपवाद का परिणाम अमान्य डब्लूसीएफ प्रॉक्सी नहीं होता है तो लूप को जारी रखने का इरादा है। मुझे टाइम-आउट त्रुटियों या सर्वर साइड गलती अपवादों की उम्मीद है। इनमें से कोई भी विशेष कार्यक्षमता के लिए, पकड़ में किसी भी कमजोर कार्यक्षमता की आवश्यकता नहीं है। हालांकि, हम लॉग फ़ाइल की समीक्षा करेंगे और इस तरह के किसी भी अपवाद की जांच की जाएगी। – Terry
मुझे समांतर के बारे में क्या उलझन में आया। फोरेच यह था कि मैंने यह भी माना कि यह एक अवरुद्ध कॉल होना चाहिए जब तक कि पूल में सभी धागे पूर्ण नहीं होते हैं (अपवाद कैश किए जाते हैं या नहीं), उदाहरण के लिए सेट ब्रेकपॉइंट पर चलने वाले धागे की संख्या आपका कैच (एग्रीगेट एक्सेप्शन एजीजीईएक्स) ब्लॉक, वीएस 2010 थ्रेड व्यूअर में 20 थ्रेड के रूप में रिपोर्ट करेगा। तो मुझे sysinternals मिल गया और vshost निष्पादन योग्य डीबग किया जा रहा देखा और यह यूआई और संदेश पंप सहित 22 धागे भी दिखाया। – Terry
आगे, लूप के भीतर उठाए गए कार्यक्रम, फ़ंक्शन निष्पादित होने के बाद और अपवाद फेंक रहे थे और अंततः ब्लॉक चला गया है। – Terry