2010-08-11 15 views
11

C# içinde uyuyan bir konu uyandırmanın bir yolu var mı? Yani, uzun bir süre uyumak ve işlenmek istediğinizde uyandırmak mı?Bir uyku ipi uyandırmanın bir yolu var mı?

+0

Tam olarak hangi ayarda? Bunu anlamlı bir şekilde cevaplayabilmek için kullandığınız platform ve/veya iş parçacığı modeli hakkında daha fazla bilgiye ihtiyacımız var. – Gian

+0

Uyumaya nasıl koyduğuna bağlı. – zneak

+1

Kesinlikle en azından bu sorunun hangi programlama diliyle ilgili olduğunu söylemelisiniz. – scy

cevap

14

bir AutoResetEvent nesne (veya başka bir WaitHandle uygulanması) uyku kullanılabilir:

// launch a calculation thread 
var waitHandle = new AutoResetEvent(false); 
int result; 
var calculationThread = new Thread(
    delegate 
    { 
     // this code will run on the calculation thread 
     result = FactorSomeLargeNumber(); 
     waitHandle.Set(); 
    }); 
calculationThread.Start(); 

// now that the other thread is launched, we can do something else. 
DoOtherStuff(); 

// we've run out of other stuff to do, so sleep until calculation thread finishes 
waitHandle.WaitOne(); 
3

Eğer iş parçacığınız Sleep numaralı aramanın içindeyse, o zaman (genellikle) onu uyandırmanın bir yolu yoktur. (Fark ettiğim tek istisna, Java'nın, başka bir iş parçacığının thread.interrupt() numaralı telefonu çağırması durumunda bir uykunun erkenden bitmesine izin vermesidir.)

Konuştuğunuz model bir olay için çağrı yapıyor gibi görünüyor: Bir döngü, bir olayın ateşlenmesini bekler. Olay şu anda unset ise, iplik başka bir iş parçacığı olayı tetikleyene kadar "uyur". Bu noktada, uyku ipliğiyle uyanır ve bir başka olayı beklemek için uyuduğu sırada bir sonraki zamana kadar çalışmasına devam eder.

+0

@John, bu bilgiyi eklemek için düzenlerken yorumunuzu eklediniz :). –

+0

Yeterince adil yorumumu kaldırırım :) –

0

this İpliği yardım eder misiniz? C#, Olay işleme iş parçacığı için good functionality sahiptir. Çalışmamın çoğunu Python'da yaptım, ama C# iş parçacığı engelleme için katı kitaplıklara sahip görünüyor. başka bir akıştan bir sinyal alınana kadar

1

iyi çözüm varsayılan TaskFactory ile Task nesneleri kullanmak olacaktır. Bu API (.NET 4.0'da tanıtılmıştır), iş çalma sıralarına ve tüm bu güzel şeylere sahip bir iş parçacığı havuzu kullanır.

.NET 4.0 kullanılamıyorsa, yerleşik bir iş kuyruğu olan (bazı havuz dengelemesi yapan ancak 4.0 iş parçacığı havuzu ile aynı kapsamda olmayan) ThreadPool'u kullanın.

Eğer gerçekten kendiniz yapıyorsanız, o zaman .NET 4.0'da eklenen bir engelleme tüketici/yapımcı kuyruğu olan BlockingCollection<T> öneririm.

gerçekten gerekir yaparsanız kendiniz ve o zaman işin lock korumalı kuyrukta birlikte ManualResetEvent veya AutoResetEvent bir kullanabilir, .NET 4.0 kullanamaz.

3
public void WakeUp() 
{ 
    if (Thread.CurrentThread.ThreadState == ThreadState.WaitSleepJoin) 
    Thread.CurrentThread.Interrupt(); 
} 
+1

Bu iş parçacığı ve uyandırmayacak. – Danpe

+1

@Danpe İpliği iptal ettiğinden şüpheliyim, o zaman buna bir kesinti demenin anlamı ne olurdu? Bunu okuyun: http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt(v=vs.110).aspx Bu istisnayı yakalamak zorunda kalacaksınız. –

+0

OP'nin ne istediğini bu şekilde gerçekleştiremezsiniz. İş parçacığı kodunun, işletim sisteminin iş parçacığının yeniden işlenmesini sağlamak için sinyal vermesini beklediği kesin bir "bekleme" noktası olmalıdır. 'Sleep' veya' SpinWait' veya 'Yield' için yapılan çağrılar diziyi' WaitSleepJoin' durumuna geçirir. – Slight

İlgili konular