2015-04-27 21 views
5

Son zamanlarda bazı çok iş parçacıklı konsol uygulamaları üzerinde çalışıyorum ve bunun nasıl yapıldığını merak ediyordum. I uygulama tarafından oluşturulan parçacığı miktarını kontrol etmek için, bu kodu kullanın: dolayı ise döngü,Konsol çıkışı engellenmeden döngü

foreach(string s in File.ReadAllLines("file.txt")){ 
    while (threads >= maxThreads) ; 
    Thread t = new Thread(() => { 
     threads++; 
     //thread code - make network request using 's' 
     Console.WriteLine("TEST"); 
     threads--; 
     Thread.CurrentThread.Abort(); 
    }); 
    t.start(); 
} 

Bununla birlikte, oluşturulan içinde Console.WriteLine yöntem bloke edilir ve bir sonraki serbest iplik kullanılabilir kadar göstermez .

Döngüyü Console.WriteLine numaralı çağrıyı engellemekten engelleyebileceğim herhangi bir yol var mı?

DÜZENLEME - while döngüsünde ters durum.

+0

Olanlardan olduğuna emin misin? Konu zaten başladıysa, ana iş parçacığında meşgul döngü tarafından engellenmez. – Blorgbeard

+2

Ayrıca, bundan kaçınmak için konsola birden çok iş parçacığından yazma. Konsol çok dişli dostu değildir. Konularınız konsolu beklerken birbirinizi bloke edecek. – Blorgbeard

+0

Oluşabilecek başka bir sorun göremiyorum - oluşturulan iş parçacığı, birkaç saniye süren, zaman alıcı bir işlevsellik (web istekleri gibi) çalıştırıyor. Ben mutlithreaded uygulamaları ile çok deneyimli değilim, bu yüzden ben de aynı soruyu soruyorum sanırım ... – rodit

cevap

6

GÜNCELLEME Yorumlarınıza dayanarak

...

while (threads >= maxThreads) ; 

iplik durum değişikliğini beklemek üzere iyi bir yol değildir çizgi, o CPU neden olacaktır çünkü while ifadesinde dönecek. Bunun yerine, Semaphore gibi iş parçacığı senkronizasyonu için amaçlanan mekanizmalardan birini kullanın.

Burada çok benzer bir durum için kullanılan bir SemaphoreSlim'in an example'u. vb while döngüsü ve Thread.Abort (veya thread.suspned) kullanarak

class TheClub  // No door lists! 
{ 
    static SemaphoreSlim _sem = new SemaphoreSlim (3); // Capacity of 3 

    static void Main() 
    { 
    for (int i = 1; i <= 5; i++) new Thread (Enter).Start (i); 
    } 

    static void Enter (object id) 
    { 
    Console.WriteLine (id + " wants to enter"); 
    _sem.Wait(); 
    Console.WriteLine (id + " is in!");   // Only three threads 
    Thread.Sleep (1000 * (int) id);    // can be here at 
    Console.WriteLine (id + " is leaving");  // a time. 
    _sem.Release(); 
    } 
} 
+0

Cevabınız için teşekkürler, ancak bu soruda bir hataydı. Çok aptalım - Soruyu düzenleyeceğim! – rodit

+1

@ rodit Noktalı virgülü çıkarın. – farukdgn

+0

Düzenlemeden sonra bile 'while' döngüsünüz iş parçacığı oluşturma işlemini ve Console.WriteLine öğelerini içermez; çünkü bu süre içinde'; 'sonradan, ve while gövdesine birden çok deyim eklemek için {} yoktur. –

4

CPU yoğun ve iplik senkronizasyon için doğru bir yol değildir. Manuel ve AutoResetEvents'ı keşfedin. İş parçacığı senkronizasyonu söz konusu olduğunda çok etkilidirler ve CPU'nuzu yükseltmezler.

+0

Bir semafor daha uygundur. –