2010-11-25 20 views
9

“raw” .net zamanlayıcıyı elden çıkardığınızda, Win32 zamanlayıcısı yok edildikten sonra çağrılacak bir bekleme tutamacını geçirebilir ve geri arama çağrılmayacağınızı varsayabilirsiniz. (Ve zamanlayıcı, GC tarafından "ölü" olarak kabul edilecektir)Bir System.Timers.Timer ürününü nasıl güvenle atabilirim?

Bunu System.Timers.Timer ile nasıl yapabilirim?

cevap

0

System.Timers.Timer ve System.Windows.Forms.Timer'in her ikisi de ThreadPool'u kullanarak işletim sistemi zamanlayıcısı için bir tanıtıcıya sahip değildir, bu nedenle atılmış bir yerel zamanlayıcı kaynağı yoktur - yalnızca tamamlanmış bir iş parçacığı . ThreadPool tarafından geri dönüştürülen bir iş parçacığı yakalayabileceğinden emin değilim, ama yanılıyor olabilirim.

Belki rulo olabilir senin (bu test etmedim ve Dispose bir ManualResetEvent alarak daha yararlı olabilir) kendi: Eğer elden aramadan önce

void Run() 
{ 
    ManualResetEvent resetEvent = new ManualResetEvent(false); 

    System.Threading.Timer timer = new System.Threading.Timer(delegate { Console.WriteLine("Tick"); }); 
    timer.Dispose(resetEvent); 

    MyTimer t = new MyTimer(); 
    t.Interval = 1000; 
    t.Elapsed += delegate { t.Dispose(resetEvent); }; 

    resetEvent.WaitOne(); 
} 


public class MyTimer : System.Timers.Timer 
{ 
    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
    } 

    public virtual void Dispose(WaitHandle handle) 
    { 
     handle.SafeWaitHandle.Close(); 
     Dispose(); 
    } 
} 
+0

System.Timers.Timer Diske Olayı, System.Threading.Timer Dispose yöntemini çağırır göndermez işten çıkar. –

+0

@Ian Olay, “Component.Dispose (disposing)” içinde aranıyor. Bu yüzden, base.Dispose() öğesini çağırmadan önce WaitHandle sinyalini sağlamanız ve özel Atımı (WaitHandle) kullanmanız gerekir. –

3

bir bayrak ayarlayın ve bu bayrağı kontrol Geçen işleyiciniz. Zamanlayıcı ateş verse bile, bayrak, ilişkili herhangi bir işleyici kodunun çalışmasını engeller. Zamanlayıcı için bir sarıcı yazarak bu deseni resmileştirebilirsiniz. Bayrağınızın farklı iş parçacıklarından erişileceği için uçucu olduğu işaretli olduğundan emin olun.

+0

Uçucu yeterince iyi değil, bir MRE veya Kilitli kullanın. –

+0

@ Uçucu bayrak, aramadan önce ayarlanmışsa, daha sonra geçen bir olay meydana gelirse, zamanlayıcı bir iplik görecektir. Burada gördüğünüz problem nedir? –

+0

Thread.MemoryBarrier –

İlgili konular