2009-02-01 10 views
5
namespace ThPool 
{ 
    class Program 
    { 
     private static long val = 0; 
     private static string obj = string.Empty; 

     static void Main(string[] args) 
     { 
      Thread objThread1 = new Thread(new ThreadStart(IncrementValue)); 
      objThread1.Start(); 
      Thread objThread2 = new Thread(new ThreadStart(IncrementValue)); 
      objThread2.Start(); 
      objThread1.Join(); 
      objThread2.Join(); 

      Console.WriteLine("val=" + val + " however it should be " + (10000000 + 10000000)); 

      Console.ReadLine(); 
     } 

     private static void IncrementValue() 
     { 
      for (int i = 0; i < 10000000; i++) 
      { 
       Monitor.Enter(obj); 
       val++; 
       Monitor.Exit(obj); 
      } 
     } 
    } 
} 

मैं धागा & पर नजर रखने के प्रतिस्थापन में ThreadPool वर्ग उपयोग कैसे करूँ?कैसे ThreadPool वर्ग का उपयोग करने के

+0

हाय हुडा क्या आप इसे थोड़ा बेहतर प्रारूपित कर सकते हैं? –

+0

अपने कार्यकर्ता विधियों के इंटीरियर को ट्राइक-कैच के साथ सुरक्षित रखना याद रखें क्योंकि वर्कर थ्रेड में अपवाद केवल चुपचाप –

उत्तर

0

आप BeginInvoke, EndInvoke का उपयोग कर सकते हैं। यह दृश्यों के पीछे थ्रेडपूल का उपयोग करता है लेकिन प्रोग्राम करना आसान है। यहाँ देखें:

http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

1

आप ThreadPool.QueueUserWorkItem() ध्यान देना चाहिए। यह एक प्रतिनिधि वस्तु लेता है जो थ्रेडपूल थ्रेड पर चलाया जाता है, जो एक राज्य वस्तु में गुज़रता है।

अर्थात

string fullname = "Neil Barnwell"; 
ThreadPool.QueueUserWorkItem(state => 
{ 
    Console.WriteLine("Hello, " + (string)state); 
}, fullname); 

Control.BeginInvoke() से भ्रमित नहीं होना है। यह उस थ्रेड पर कॉल को मार्शल करेगा जिसने नियंत्रण बनाया है, इस मुद्दे को रोकने के लिए जहां क्रॉस-थ्रेड कॉल नियंत्रण को नियंत्रित करता है। यदि आप विंडोज़ फॉर्म पर सरल मल्टी-थ्रेडिंग चाहते हैं, तो BackgroundWorker देखें।

2
EventWaitHandle[] waitHandles = new EventWaitHandle[2]; 


for(int i = 0; i < 2; i++) 
{ 
    waitHandles[i] = new AutoResetEvent(false); 
    ThreadPool.QueueUserWorkItem(state => 
    { 
     EventWaitHandle handle = state as EventWaitHandle; 
     for(int j = 0; j < 10000000; j++) 
     { 
      Interlocked.Increment(ref val); //instead of Monitor 
     } 
     handle.Set(); 
    }, waitHandles[i]); 
} 

WaitHandle.WaitAll(waitHandles); 
Console.WriteLine("val=" + val + " however it should be " + (10000000 + 10000000)); 
4

थ्रेड पूल का उपयोग करने के कुछ तरीके हैं। अपने कार्य के लिए, आपको निम्नलिखित को देखना चाहिए।

  • यदि आपको केवल QueueUserWorkItem का उपयोग करने का सबसे आसान तरीका चलाने की आवश्यकता है, जो बस चलाने के लिए एक प्रतिनिधि लेता है। नुकसान यह है कि आपके पास नौकरी पर थोड़ा नियंत्रण नहीं है। प्रतिनिधि एक मूल्य वापस नहीं कर सकता है, और आप नहीं जानते कि रन कब पूरा हो गया है।
  • यदि आप थोड़ा अधिक नियंत्रण चाहते हैं, तो आप प्रतिनिधियों के BeginInvoke/EndInvoke इंटरफ़ेस का उपयोग कर सकते हैं। यह थ्रेड पूल थ्रेड पर चलाने के लिए कोड शेड्यूल करता है। IAsyncResultBeginInvoke द्वारा लौटाए गए हैंडल के माध्यम से आप स्थिति की क्वेरी कर सकते हैं, और आप EndInvoke के माध्यम से परिणाम (साथ ही कार्यकर्ता धागे पर कोई अपवाद) प्राप्त कर सकते हैं।

ठीक से Monitor पर Enter/Exit का उपयोग करने के लिए आपको लगता है कि Exit हमेशा कहा जाता है बनाने के लिए किया है। इसलिए आपको अंत में ब्लॉक में अपना Exit कॉल करना चाहिए।

हालांकि, अगर आप Enter के लिए एक टाइमआउट मान की आपूर्ति करने की जरूरत नहीं है, तो आप बहुत से बेहतर होगा सिर्फ lock कीवर्ड, जो Enter और Exit कॉल की एक उचित सेट में संकलित का उपयोग कर।

+0

को मारते हैं आप रन को पूरा करते समय निर्धारित करने के लिए ऑटोरसेट इवेंट या मैनुअल रीसेट इवेंट का उपयोग कर सकते हैं (जैसा कि पाब्लिटो के उत्तर में है)। – Cocowalla

0

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

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