दिलचस्प पोस्ट
जावा 8 लैंबदास, फ़ंक्शन। पहचान () या टी-> टी सिग्नेशन और सिग्नल के बीच अंतर क्या है? कुंजी के साथ लूप और सरणी के लिए टहलना जावा में एकाधिक प्राप्तकर्ताओं को मेल भेजें मैं ओरेकल में एक अल्पविराम से सीमांकित सूची में कई पंक्तियों को कैसे जोड़ सकता हूं? नकारात्मक मूल्यों के साथ मॉड्यूलो ऑपरेटर सफारी / क्रोम (वेबकिट) – iframe ऊर्ध्वाधर स्क्रॉलबार छुपा नहीं जा सकता जावास्क्रिप्ट में किसी पाठ फ़ाइल में जेसन ऑब्जेक्ट लिखना jQuery के सभी divs प्राप्त करें जो कि क्लास विशेषता नहीं है I क्या $ _SERVER पर विश्वास करना सुरक्षित है? कैसे सी # में बहुआयामी (2 डी) सरणी का आकार बदलना है? लूप अनुकूलन के लिए एंड्रॉइड में वेबव्यू को यूआरएल लोड करते हुए प्रगति कैसे प्रदर्शित करें? एक MVC बाल कार्रवाई क्या है? बहिष्कृत SMIL SVG एनीमेशन सीएसएस या वेब एनिमेशन प्रभाव (हॉवर, क्लिक करें) के साथ बदल दिया

क्या किसी थ्रेड (थ्रेड। अपॉर्टेन्ट विधि) को छोड़ने जैसे कार्य को रद्द करना संभव है?

हम इस तरह एक थ्रेड को रोक सकते हैं:

Thread thread = new Thread(SomeMethod); . . . thread.Abort(); 

लेकिन मैं एक टास्क को रद्द कर सकता हूं (नेट 4.0 में) उसी तरह रद्द करने की प्रक्रिया से नहीं। मैं तुरंत टास्क को मारना चाहता हूं

Solutions Collecting From Web of "क्या किसी थ्रेड (थ्रेड। अपॉर्टेन्ट विधि) को छोड़ने जैसे कार्य को रद्द करना संभव है?"

  1. आपको थ्रेड का उपयोग नहीं करना चाहिए।
  2. कार्य रद्द किए जा सकते हैं लेकिन निरस्त नहीं किए गए

धागा । सहायक () विधि (गंभीर रूप से) पदावनत है।

थ्रेड्स और टास्क को रोकने के दौरान सहयोग करना चाहिए, अन्यथा आप सिस्टम को अस्थिर / अपरिभाषित स्थिति में छोड़ने का जोखिम चलाते हैं।

यदि आपको एक प्रक्रिया चलाने और इसे बाहर से मारने की आवश्यकता है, तो एकमात्र सुरक्षित विकल्प इसे अलग ऐपडोमेन में चलाया जा सकता है।

एक धागा समापन का उपयोग नहीं करने पर मार्गदर्शन विवादास्पद है। मुझे लगता है कि इसके लिए अभी भी एक जगह है लेकिन असाधारण परिस्थितियों में। हालांकि आपको हमेशा इसके चारों ओर डिजाइन करने का प्रयास करना चाहिए और इसे अंतिम उपाय के रूप में देखना चाहिए।

उदाहरण;

आपके पास एक सरल विंडोज़ प्रपत्र अनुप्रयोग है जो ब्लॉकिंग तुल्यकालिक वेब सेवा से जुड़ता है। जिसके भीतर यह एक समानांतर लूप के भीतर वेब सेवा पर फ़ंक्शन कार्यान्वित करता है।

 CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions po = new ParallelOptions(); po.CancellationToken = cts.Token; po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(iListOfItems, po, (item, loopState) => { Thread.Sleep(120000); // pretend web service call }); 

इस उदाहरण में कहें, ब्लॉकिंग कॉल को पूरा करने में 2 मिनट लगते हैं। अब मैं अपने मैक्सडेग्री ओफ़पेरललिस्म को सेट करने के लिए कहता हूं प्रोसेसरकाउंट iListOfItems है प्रक्रिया के भीतर 1000 वस्तुओं के भीतर।

उपयोगकर्ता प्रक्रिया बटन पर क्लिक करता है और लूप शुरू होता है, हमारे पास iListOfItems संग्रह में 1000 आइटम के साथ 20 अप करने के लिए 'अप-टू' है। प्रत्येक थियेटर अपने थ्रेड पर कार्यान्वित करता है प्रत्येक धागा एक अग्रभूमि धागा का उपयोग करेगा जब समानांतर द्वारा बनाया जाएगा। ForEach इसका अर्थ मुख्य आवेदन शटडाउन की परवाह किए बिना, सभी डोमेन के समाप्त होने तक ऐप डोमेन को जिंदा रखा जाएगा।

हालांकि उपयोगकर्ता को किसी कारण के लिए आवेदन को बंद करना होगा, कहते हैं कि वे फॉर्म बंद कर देते हैं। ये 20 थ्रेड्स तब तक जारी रहेगा जब तक सभी 1000 आइटम संसाधित नहीं होते। यह इस परिदृश्य में आदर्श नहीं है, क्योंकि आवेदन उपयोगकर्ता के रूप में बाहर नहीं निकलता और पर्दे के पीछे चलना जारी रखता है, क्योंकि कार्य प्रबंधक में एक नज़र रखकर देखा जा सकता है।

कहें कि उपयोगकर्ता पुनः ऐप को फिर से बनाने की कोशिश करता है (वीएस 2010), यह रिपोर्ट करता है कि एक्सई लॉक है, तो उन्हें इसे मारने के लिए कार्य प्रबंधक में जाना होगा या सिर्फ 1000 आइटम संसाधित होने तक प्रतीक्षा करें।

मैं कहने के लिए आप पर दोष नहीं होगा, लेकिन ज़ाहिर है! मुझे इन थ्रेड्स को रद्द करना टोकनसॉर्स ऑब्जेक्ट का उपयोग करना रद्द करना चाहिए और रद्द करना बंद कर देना चाहिए … लेकिन इसके साथ .net 4.0 जैसी कुछ समस्याएं हैं I सबसे पहले यह अभी भी एक धागा समाप्त होने का परिणाम नहीं है जो थ्रेड समापन के बाद अपवाद अपवाद की पेशकश करेगा, इसलिए ऐप डोमेन को थ्रेड को सामान्य रूप से समाप्त होने की प्रतीक्षा करने की आवश्यकता होगी, और इसका मतलब है कि अंतिम अवरोधक कॉल के लिए इंतजार करना, जो आखिरी चलने वाले पुनरावृत्ति (थ्रेड) होगा, जो आखिरकार po.CancellationToken.ThrowIfCancellationRequestedpo.CancellationToken.ThrowIfCancellationRequestedpo.CancellationToken.ThrowIfCancellationRequested । उदाहरण के तौर पर इसका मतलब यह होगा कि एप डोमेन अभी तक 2 मिनट तक जीवित रह सकता है, भले ही फ़ॉर्म बंद कर दिया गया हो और फोन को रद्द कर दिया गया हो।

नोट करें कि रद्द करना रद्द करने पर कॉलिंगटोकनसार्स प्रोसेसिंग धागा (एस) पर एक अपवाद नहीं डालता है, जो वास्तव में अवरुद्ध कॉल को अवरुद्ध करने के लिए अवरोध करने और निष्पादन को रोकने के लिए वास्तव में कार्य करेगा। एक अपवाद सभी अन्य थ्रेड्स (समवर्ती पुनरावृत्तियों) अंततः समाप्त और वापस करने के लिए तैयार होने के लिए तैयार एक अपवाद है, अपवाद प्रारंभिक धागा (जहां लूप घोषित किया गया है) में फेंक दिया गया है।

मैंने रद्द विकल्प का उपयोग करने के लिए रद्द करना टोकनसॉर ऑब्जेक्ट नहीं चुना। यह बेकार है और तर्कसंगत रूप से अपवादों द्वारा कोड के प्रवाह को नियंत्रित करने के प्रसिद्ध विरोधी पट्टी का उल्लंघन करता है।

इसके बजाय, यह तर्कसंगत है कि एक साधारण धागा सुरक्षित संपत्ति को लागू करने के लिए 'बेहतर' यानी बूल स्टॉप एक्सपोस्टिंग फिर पाश के भीतर, रोक के मूल्य की जाँच करें, और अगर मूल्य बाहरी प्रभाव से सही पर सेट हो जाता है, तो हम एक वैकल्पिक पथ को गहराई से बंद करने के लिए ले सकते हैं। चूंकि हमें कॉल रद्द नहीं करनी चाहिए, यह रद्द करना टोकनसॉर्स की जाँच को रोकता है। अन्यथा एक अन्य विकल्प होगा जो अन्य विकल्प होगा।

निम्नलिखित की तरह कुछ यदि स्थिति लूप के भीतर उपयुक्त हो;

अगर (लूपस्टेट। चोटीएक्सिट कंटेंट इटेरेशन || लूपस्टेट.इस्पेस्प्शनल || स्टॉप एक्सपेंटेटिंग) {लूपस्टेट .टॉप (); वापसी;}

चलना अब एक 'नियंत्रित' तरीके से बाहर निकल पड़ेगा और साथ ही आगे चलना रद्द कर दिया जाएगा, लेकिन जैसा कि मैंने कहा, यह हमारे चलने और अवरुद्ध कॉल (कॉलों) पर इंतजार करने के लिए बहुत कम है, जो प्रत्येक पुनरावृत्ति समानांतर लूप धागा), क्योंकि ये प्रत्येक धागे को पूरा करने से पहले यह जांचना होगा कि क्या इसे रोकना चाहिए।

संक्षेप में, जैसा कि उपयोगकर्ता फॉर्म को बंद करता है, 20 थ्रेड्स को स्टॉप के माध्यम से रोकने के लिए सिग्नल किया जाएगा, लेकिन वे केवल तब ही रोक देंगे जब वे अपने लंबे समय से चलने वाले फ़ंक्शन कॉल को पूरा कर लेंगे।

हम इस तथ्य के बारे में कुछ भी नहीं कर सकते हैं कि आवेदन डोमेन हमेशा जीवित रहेगा और केवल तब ही जारी किया जाएगा जब सभी अग्रभूमि धागे पूरा हो जाएंगे। और इसका मतलब है कि लूप के भीतर किए गए किसी भी अवरुद्ध कॉल को पूरा करने के लिए इंतजार करने से संबंधित विलंब होगा।

केवल एक सच थ्रेड अवरोध ब्लॉकिंग कॉल को बाधित कर सकता है, और आपको सिस्टम को अस्थायी / अपरिभाषित अवस्था में छोड़ने के लिए कम से कम करना चाहिए, जो कि आप निरस्त किए गए थ्रेड के अपवाद हैंडलर में सबसे अच्छा कर सकते हैं जो प्रश्न के बिना जाता है। क्या यह उचित है कि प्रोग्रामर को तय करने के लिए एक मामला है, जो संसाधनों को बनाए रखने के लिए चुना गया है और उन्हें थ्रेड के अंत में ब्लॉक में बंद करना कितना आसान है। आप एक टोकन के साथ पंजीकरण रद्द कर सकते हैं ताकि अर्ध परिपाटी अर्थात् रद्द किया जा सके

 CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions po = new ParallelOptions(); po.CancellationToken = cts.Token; po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(iListOfItems, po, (item, loopState) => { using (cts.Token.Register(Thread.CurrentThread.Abort)) { Try { Thread.Sleep(120000); // pretend web service call } Catch(ThreadAbortException ex) { // log etc. } Finally { // clean up here } } }); 

लेकिन यह अभी भी घोषित धागा में एक अपवाद का परिणाम देगा।

समस्त बातों को ध्यान में रखते हुए, parallel.loop constructs का उपयोग कर कॉल अवरुद्ध करने में बाधा विकल्प पर एक तरीका हो सकता था, पुस्तकालय के अधिक अस्पष्ट भागों के उपयोग से परहेज। लेकिन घोषणा करने के तरीके में एक अपवाद को फेंकने से बचने और बचने का कोई विकल्प क्यों नहीं है मुझे संभावित निरीक्षण के रूप में चला जाता है

लेकिन मैं एक टास्क को रद्द कर सकता हूं (नेट 4.0 में) उसी तरह रद्द करने की प्रक्रिया से नहीं। मैं तुरंत टास्क को मारना चाहता हूं

अन्य उत्तरदाताओं ने आपको यह नहीं बताया है। लेकिन हाँ, आप इसे कर सकते हैं आप Thread.Abort() आपूर्ति कर सकते हैं। Thread.Abort() रूप में प्रतिनिधि को टास्क के रद्द करने के तंत्र द्वारा बुलाया जाना है। यहां बताया गया है कि आप इसे कैसे कॉन्फ़िगर कर सकते हैं:

 class HardAborter { public bool WasAborted { get; private set; } private CancellationTokenSource Canceller { get; set; } private Task<object> Worker { get; set; } public void Start(Func<object> DoFunc) { WasAborted = false; // start a task with a means to do a hard abort (unsafe!) Canceller = new CancellationTokenSource(); Worker = Task.Factory.StartNew(() => { try { // specify this thread's Abort() as the cancel delegate using (Canceller.Token.Register(Thread.CurrentThread.Abort)) { return DoFunc(); } } catch (ThreadAbortException) { WasAborted = true; return false; } }, Canceller.Token); } public void Abort() { Canceller.Cancel(); } } 

अस्वीकरण : ऐसा मत करो

यहां ऐसा करने का एक उदाहरण है जो नहीं करना है:

  var doNotDoThis = new HardAborter(); // start a thread writing to the console doNotDoThis.Start(() => { while (true) { Thread.Sleep(100); Console.Write("."); } return null; }); // wait a second to see some output and show the WasAborted value as false Thread.Sleep(1000); Console.WriteLine("WasAborted: " + doNotDoThis.WasAborted); // wait another second, abort, and print the time Thread.Sleep(1000); doNotDoThis.Abort(); Console.WriteLine("Abort triggered at " + DateTime.Now); // wait until the abort finishes and print the time while (!doNotDoThis.WasAborted) { Thread.CurrentThread.Join(0); } Console.WriteLine("WasAborted: " + doNotDoThis.WasAborted + " at " + DateTime.Now); Console.ReadKey(); 

नमूना कोड से आउटपुट

हालांकि, धागा को रोकना संभव है, व्यवहार में यह लगभग हमेशा ऐसा करने के लिए बहुत बुरा विचार है। एक धागा का अर्थ है कि थ्रेड को स्वयं के बाद साफ करने का मौका नहीं दिया जाता है, संसाधनों को हटा दिया गया है, और अज्ञात राज्यों में चीजें।

व्यवहार में, यदि आप एक धागा को रोकते हैं, तो आपको केवल प्रक्रिया को मारने के साथ ही ऐसा करना चाहिए। अफसोस की बात है, बहुत सारे लोगों को लगता है कि थ्रेड एबॉर्ट कुछ रोकना और जारी रखने का एक व्यावहारिक तरीका है, ऐसा नहीं है।

चूंकि कार्य थ्रेड्स के रूप में चलाते हैं, आप उन पर थ्रेड एबोर्ट को कॉल कर सकते हैं, लेकिन सामान्य धागे के साथ आप इसे कभी भी नहीं करना चाहते, केवल आखिरी उपाय के रूप में।

 using System; using System.Threading; using System.Threading.Tasks; ... var cts = new CancellationTokenSource(); var task = Task.Run(() => { while (true) { } }); Parallel.Invoke(() => { task.Wait(cts.Token); }, () => { Thread.Sleep(1000); cts.Cancel(); }); 

रद्द करना टोकनसॉर के साथ कभी न खत्म होने वाले कार्य को रद्द करने के लिए यह एक सरल स्निपेट है।