2010-03-01 10 views
16

से ट्रैक ट्रैक करना मैं अपने .NET अनुप्रयोग से थ्रेड की एक्स संख्या शुरू करना चाहता हूं, और मैं उन्हें ट्रैक रखना चाहता हूं क्योंकि मुझे उन्हें मैन्युअल रूप से समाप्त करने की आवश्यकता होगी या कब मेरा आवेदन बाद में मेरे आवेदन को बंद कर देता है।एकाधिक थ्रेड शुरू करना और उनके .NET अनुप्रयोग

उदाहरण ==> अपने आवेदन में किसी भी बिंदु मैं थ्रेड बीटा बर्खास्त कहने के लिए सक्षम होना चाहिए पर धागा अल्फा शुरू .. थ्रेड बीटा प्रारंभ करें, फिर ..

सबसे अच्छा रास्ता खोल दिया धागे का ट्रैक रखने के क्या है .NET में और मुझे इसे समाप्त करने के लिए थ्रेड के बारे में क्या जानने की आवश्यकता है (एक आईडी?)? नमूना कोड, ट्यूटोरियल सहायक होगा।

उत्तर

14

आप अपने आप को गधा काम को बचाने और इस Smart Thread Pool इस्तेमाल कर सकते हैं। यह कार्य प्रणाली की एक इकाई प्रदान करता है जो आपको किसी भी बिंदु पर प्रत्येक धागे की स्थिति से पूछताछ करने और उन्हें समाप्त करने की अनुमति देता है।

यदि यह बहुत परेशान है, तो जैसा कि IDictionary<string,Thread> का उल्लेख किया गया है, शायद सबसे सरल समाधान है।

public class MyThreadPool 
{ 
    private IList<Thread> _threads; 
    private readonly int MAX_THREADS = 25; 

    public MyThreadPool() 
    { 
     _threads = new List<Thread>(); 
    } 

    public void LaunchThreads() 
    { 
     for (int i = 0; i < MAX_THREADS;i++) 
     { 
      Thread thread = new Thread(ThreadEntry); 
      thread.IsBackground = true; 
      thread.Name = string.Format("MyThread{0}",i); 

      _threads.Add(thread); 
      thread.Start(); 
     } 
    } 

    public void KillThread(int index) 
    { 
     string id = string.Format("MyThread{0}",index); 
     foreach (Thread thread in _threads) 
     { 
      if (thread.Name == id) 
       thread.Abort(); 
     } 
    } 

    void ThreadEntry() 
    { 

    } 
} 

आप निश्चित रूप से एक बहुत अधिक शामिल हैं और इसके साथ जटिल प्राप्त कर सकते हैं: या और भी आसान अपने धागा एक नाम से प्रत्येक देते हैं, और एक IList<Thread> का उपयोग करें। यदि आपके धागे को मारना समय संवेदनशील नहीं है (उदाहरण के लिए यदि आपको UI में 3 सेकंड में थ्रेड को मारने की आवश्यकता नहीं है) तो एक थ्रेड। जॉइन() एक बेहतर अभ्यास है।

और यदि आपने इसे पहले से नहीं पढ़ा है, तो जॉन स्कीट में "abort का उपयोग न करें" सलाह के लिए this good discussion and solution है जो SO पर आम है।

+0

से बाहर निकल सकता है, मुझे शून्य थ्रेडएन्ट्री() पर एक प्रश्न मिला, एक बार जब हम थ्रेड शुरुआती बिंदु के मुख्य अनुप्रयोग में धागे का एक से अधिक बनाते हैं, तो हम लॉन्च कर सकते हैं आपके द्वारा निर्दिष्ट धागे की संख्या के अनुसार उस धागे पर कोई अन्य अनुप्रयोग। – shawn

1

इस बात पर निर्भर करता है कि आपको कितना परिष्कृत होना चाहिए। आप अपने स्वयं के थ्रेडपूल को सहायक तरीके से लागू कर सकते हैं आदि। हालांकि, मुझे लगता है कि यह एक सूची/सरणी को बनाए रखने और तदनुसार संग्रह से/थ्रेड को हटाने के रूप में सरल है।

आप एक शब्दकोश संग्रह का भी उपयोग कर सकते हैं और उन्हें पुनः प्राप्त करने के लिए अपनी खुद की विशेष कुंजी का उपयोग कर सकते हैं यानी गइड्स/स्ट्रिंग्स।

2

अपना धागा बनाने के बाद, आप इसकी नाम संपत्ति सेट कर सकते हैं। मान लें कि आप कुछ संग्रह में संग्रहीत आप पुनः प्राप्त करने के लिए (और गर्भपात) में LINQ के माध्यम से आसानी से पहुँच सकते हैं यह:

var myThread = (select thread from threads where thread.Name equals "myThread").FirstOrDefault(); 
if(myThread != null) 
    myThread.Abort(); 
1

वाह, वहाँ इतने सारे जवाब हैं ..

  1. आप बस का उपयोग कर सकते धागे को पकड़ने के लिए एक सरणी, यह केवल तभी काम करेगा जब सरणी तक पहुंच अनुक्रमिक होगी, लेकिन यदि आपके पास इस सरणी को एक्सेस करने वाला कोई अन्य थ्रेड होगा, तो आपको
  2. एक्सेस सिंक्रनाइज़ करने की आवश्यकता होगी, आप थ्रेड पूल का उपयोग कर सकते हैं, लेकिन थ्रेड पूल बहुत सीमित है और केवल थ्रेड की निश्चित मात्रा पकड़ सकता है।
  3. ऊपर वर्णित अनुसार, आप अपना खुद का थ्रेड पूल बना सकते हैं, जो सुरक्षित संग्रह की शुरुआत के साथ .NET v4 में बहुत आसान हो जाता है।
  4. आप उन्हें म्यूटेक्स ऑब्जेक्ट की एक सूची धारण करके प्रबंधित कर सकते हैं जो निर्धारित करेगा कि उन धागे को कब खत्म करना चाहिए, थ्रेड प्रत्येक बार कुछ करने से पहले म्यूटेक्स से पूछेंगे, और यदि सेट सेट हो जाए, तो आप म्यूट्स का प्रबंधन कर सकते हैं कहीं से भी, और चूंकि म्यूटेक्स डिफेंसिशन थ्रेड-सुरक्षित द्वारा हैं, यह काफी आसान है ..

मैं अन्य 10 तरीकों के बारे में सोच सकता हूं, लेकिन वे काम करते हैं। अगर वे आपकी जरूरतों को पूरा नहीं करते हैं तो मुझे बताएं।

3

आप धागे का एक शब्दकोश बनाने और उन्हें पहचान-पत्र असाइन करते हैं, की तरह कर सकते हैं:

Dictionary<string, Thread> threads = new Dictionary<string, Thread>(); 
for(int i = 0 ;i < numOfThreads;i++) 
{ 
    Thread thread = new Thread(new ThreadStart(MethodToExe)); 
    thread.Name = threadName; //Any name you want to assign 
    thread.Start(); //If you wish to start them straight away and call MethodToExe 
    threads.Add(id, thread); 
} 

आप एक आईडी के खिलाफ धागे को बचाने के लिए आप बाद में एक सूची का उपयोग कर सकते हैं और बस को मारने के लिए यह बताना नहीं चाहते, तो धागे।

और जब आप उन्हें समाप्त करना चाहते हैं, तो आप उन्हें रोक सकते हैं। बेहतर MethodToExe में कुछ शर्त है जो थ्रेड को थ्रेड को समाप्त करने की इजाजत देने की अनुमति देता है। की तरह कुछ:

void MethodToExe() 
{ 
    while(_isRunning) 
    { 
     //you code here// 
     if(!_isRunning) 
     { 
      break; 
     } 
     //you code here// 
    } 
} 

गर्भपात करने के लिए आप शब्दकोश गणना और Thread.Abort() कॉल कर सकते हैं।पकड़ने के लिए तैयार रहें ThreadAbortException

+0

@ cornerback84 मैं थ्रेड.एबॉर्ट() के उपयोग के खिलाफ सलाह दूंगा ... धागे को पृष्ठभूमि में सेट करना बेहतर है। – Kiril

+0

हां, लेकिन मैं केवल यह दिखा रहा था कि इसे कैसे किया जाए। यही कारण है कि मैंने उसे कुछ शर्त रखने का सुझाव दिया जिसमें वह धागे को रोक सकता है। यह हो सकता है, या सॉकेटएक्सप्शन जैसे किसी भी अपवाद पर जिस पर कोई मेथडो – ata

3

मैं एक ऐसी ही सवाल पूछा और अच्छा जवाब में से एक गुच्छा प्राप्त किया: Shutting down a multithreaded application

नोट: मेरे सवाल का एक सुंदर बाहर निकलने की जरूरत नहीं थी, लेकिन लोगों को अभी भी सिफारिश की है कि मैं शान से की पाश से बाहर निकलने के प्रत्येक धागा

Thread thread = new Thread(new ThreadStart(testObject.RunLoop)); 
thread.IsBackground = true; 
thread.start(); 

पसंदीदा तरीका शुरू करने और धागे में है का प्रबंधन करने के:

मुख्य बात को याद है कि अगर आप से बचने के लिए चाहते हैं कि आपके धागे आप पृष्ठभूमि के लिए अपने सभी धागे स्थापित करना चाहिए समाप्त से अपनी प्रक्रिया को रोकने के है एक ThreadPool, लेकिन किसी भी कंटेनर के बारे में सिर्फ आपके धागे का संदर्भ रखने के लिए उपयोग किया जा सकता है। आपके धागे हमेशा एक ध्वज होना चाहिए जो उन्हें समाप्त करने के लिए कहेंगे और उन्हें लगातार जांच करनी चाहिए।

इसके अलावा, बेहतर नियंत्रण के लिए आप CountdownLatch के साथ अपने धागे की आपूर्ति कर सकते हैं: जब भी कोई थ्रेड अपने लूप से बाहर निकलता है तो यह CountdownLatch पर संकेत देगा। आपका मुख्य धागा CountdownLatch.Wait() विधि को कॉल करेगा और यह तब तक अवरुद्ध होगा जब तक कि सभी धागे सिग्नल नहीं हो जाते ... यह आपको ठीक से सफाई करने की अनुमति देता है और यह सुनिश्चित करता है कि सफाई शुरू करने से पहले आपके सभी थ्रेड बंद हो जाएं।

public class CountdownLatch 
{ 
    private int m_remain; 
    private EventWaitHandle m_event; 

    public CountdownLatch(int count) 
    { 
     Reset(count); 
    } 

    public void Reset(int count) 
    { 
     if (count < 0) 
      throw new ArgumentOutOfRangeException(); 
     m_remain = count; 
     m_event = new ManualResetEvent(false); 
     if (m_remain == 0) 
     { 
      m_event.Set(); 
     } 
    } 

    public void Signal() 
    { 
     // The last thread to signal also sets the event. 
     if (Interlocked.Decrement(ref m_remain) == 0) 
      m_event.Set(); 
    } 

    public void Wait() 
    { 
     m_event.WaitOne(); 
    } 
} 

यह भी है कि Thread.Abort() विधि कुछ अजीब काम करता है उल्लेख करने के लिए योग्य है:

एक धागा कॉल पर ही निरस्त करते हैं, प्रभाव एक अपवाद फेंकने के समान है; ThreadAbortException तुरंत होता है, और परिणाम अनुमानित है। हालांकि, अगर एक थ्रेड कॉल किसी अन्य थ्रेड पर निरस्त हो जाता है, तो निरंतर इंटरप्ट करता है जो भी चल रहा है। एक मौका भी है कि स्थैतिक कन्स्ट्रक्टर को निरस्त किया जा सकता है। दुर्लभ मामलों में, यह उस श्रेणी डोमेन में बनाए गए होने से उस वर्ग के उदाहरणों को रोक सकता है। में .NET Framework संस्करण 1.0 और 1.1, अंत में ब्लॉक चल रहा है, जबकि अंत में ब्लॉक निरस्त हो जाने पर थ्रेड समाप्त हो सकता है।

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

1

जैसे ही आप प्रत्येक थ्रेड शुरू करते हैं, इसे कुंजी के रूप में कुंजी और थ्रेड इंस्टेंस के रूप में एक प्रबंधित में प्रबंधित किया गया है। प्रत्येक थ्रेड से कॉलबैक का उपयोग अपने प्रबंधित थ्रेड आईडी को वापस करने के लिए करें, जिसे आप टर्मिनल से थ्रेड को हटाने के लिए उपयोग कर सकते हैं। यदि आवश्यक हो तो आप थ्रेड को निरस्त करने के लिए शब्दकोश भी चला सकते हैं। धागे पृष्ठभूमि धागे बनाओ ताकि वे समाप्त हो जाएं यदि आपका ऐप अनपेक्षित रूप से समाप्त हो जाता है।

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

संबंधित मुद्दे