2010-11-16 5 views
38
  1. मुझे यह त्रुटि संदेश क्यों मिलता है? "एसटीए थ्रेड पर एकाधिक हैंडल के लिए प्रतीक्षा करें समर्थित नहीं है।"
  2. क्या मुझे [MTAThreadAttribute] विशेषता का उपयोग करना चाहिए? अद्यतन: WPF अनुप्रयोगों के साथ काम नहीं करते हैं!

नोट: यह त्रुटि प्रतीक्षा है WaitHandle.WaitAll (doneEvents); मैं मानक WPF प्रोजेक्ट का उपयोग कर रहा हूं।एसटीए थ्रेड पर एकाधिक हैंडल के लिए WaitAll समर्थित नहीं है

private void Search() 
{ 
    const int CPUs = 2; 
    var doneEvents = new ManualResetEvent[CPUs]; 

    // Configure and launch threads using ThreadPool: 
    for (int i = 0; i < CPUs; i++) 
    { 
     doneEvents[i] = new ManualResetEvent(false); 
     var f = new Indexer(Paths[i], doneEvents[i]); 
     ThreadPool.QueueUserWorkItem(f.WaitCallBack, i); 
    } 

    // Wait for all threads in pool 
    WaitHandle.WaitAll(doneEvents); 
    Debug.WriteLine("Search completed!"); 
} 

अद्यतन: निम्नलिखित समाधान WPF अनुप्रयोगों के लिए काम नहीं करता है! एमटीएटीएचएडएट्रिब्यूट में मुख्य एप्लिकेशन विशेषता को बदलना संभव नहीं है। इसके परिणामस्वरूप निम्नलिखित त्रुटि होगी:

त्रुटि: "एसटीए थ्रेड पर एकाधिक हैंडल के लिए प्रतीक्षा करें समर्थित नहीं है।"

+0

आप महसूस करते हैं कि आप अनुप्रयोग पूरी तरह से स्थिर है, जब तक उन Indexers की जाती हैं? – liggett78

+0

हां! मुझे पता है कि। लेकिन जैसा कि यह नहीं चलता है। –

+1

http://stackoverflow.com/questions/3784510/notsupportedexception-on-waithandle-waitall –

उत्तर

17

आपके लिए अपना थ्रेडिंग करने के लिए कार्य का उपयोग करने के बारे में क्या।

http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx

var task1 = Task.Factory.StartNew(() => DoSomeWork()); 
var task2 = Task.Factory.StartNew(() => DoSomeWork()); 
var task3 = Task.Factory.StartNew(() => DoSomeWork()); 
Task.WaitAll(task1, task2, task3); 
+4

यह .NET Framework 4. है इसलिए मुझे प्रोजेक्ट को अपग्रेड करना होगा। यह एक बेहतर दृष्टिकोण विचार प्रतीत होता है! –

+2

'टास्क.रुन (() => DoSomeWork()) 'बेहतर विकल्प – gldraphael

8

एक ManualResetEvent का उपयोग करें और उस पर प्रतीक्षा करें। कार्यकर्ता धागे की संख्या पर सेट एक टास्ककाउंट वेरिएबल भी बनाए रखें, कार्यकर्ता थ्रेड कोड में कार्यकर्ता थ्रेड कोड में Interlocked.Decrement का उपयोग करें, कार्यकर्ता की आखिरी कार्रवाई के रूप में और काउंटर शून्य तक पहुंचने पर ईवेंट को सिग्नल करें।

// other worker actions... 
if (Interlocked.Decrement(ref taskCount) == 0) 
    doneEvent.Set(); 
+0

धन्यवाद यह एकमात्र समाधान प्रतीत होता है क्योंकि WaitAll (..) काम नहीं करता है। –

+0

हाँ, यह काम करेगा। बस मुख्य धागे का इलाज करना सुनिश्चित करें जैसे कि यह एक कार्य आइटम था और 'taskCount = 1' प्रारंभ करें और 'लूप' के अंत में 'कमी' और 'सेट' करें। –

6

मैं बजाय CountdownEvent वर्ग का उपयोग करने के लिए अपने कोड refactor होगा।

private void Search() 
{ 
    const int CPUs = 2; 
    var done = new CountdownEvent(1); 

    // Configure and launch threads using ThreadPool: 
    for (int i = 0; i < CPUs; i++) 
    { 
     done.AddCount(); 
     var f = new Indexer(Paths[i], doneEvents[i]); 
     ThreadPool.QueueUserWorkItem(
      (state) => 
      { 
      try 
      { 
       f.WaitCallBack(state); 
      } 
      finally 
      { 
       done.Signal(); 
      } 
      }, i); 
    } 

    // Wait for all threads in pool 
    done.Signal(); 
    done.Wait(); 
    Debug.WriteLine("Search completed!"); 
} 
+0

एनबी: .NET 4 केवल –

45

असल में मैं WaitHandle.WaitAll (doneEvents) को प्रतिस्थापित करने के लिए निम्न का उपयोग करता हूं;

foreach (var e in doneEvents) 
    e.WaitOne(); 
+1

इस विकल्प का उपयोग करने के लिए कोई डाउनसाइड्स हैं? – invertigo

+3

मैंने कोई नहीं देखा है, लेकिन मैं ब्रांड के नए कोड – Calimero100582

0

कुछ उपयोग इस तरह:

foreach (ITask Task in Tasks) 
{ 
    Task.WaitHandle = CompletedEvent; 
    new Thread(Task.Run).Start(); 
} 

int TasksCount = Tasks.Count; 
for (int i = 0; i < TasksCount; i++) 
    CompletedEvent.WaitOne(); 

if (AllCompleted != null) 
    AllCompleted(this, EventArgs.Empty); 
+1

के लिए कार्य का उपयोग करने की अनुशंसा करता हूं CompletedEvent प्रकार का सिस्टम है। थ्रेडिंग.ऑटो रीसेट इवेंट – CSharper

+0

-1 जबकि क्लीनर, मेरे लिए यह http://stackoverflow.com/a के लिए पर्याप्त रूप से अलग नहीं है/4194938/11635 –

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