System.Timers.Timer vs System.Threading.Timer


565

Son zamanlarda bazı olası zamanlayıcılar kontrol edilmiştir ve System.Threading.Timerve System.Timers.Timer(onlar iplik havuzu destekliyorlar çünkü) bana ihtiyacı olan olanlar.

Bir oyun yapıyorum ve her türlü etkinliği farklı aralıklarla kullanmayı planlıyorum.

Hangisi en iyi olurdu?

Yanıtlar:


363

Bu makale oldukça kapsamlı bir açıklama sunuyor:

" .NET Framework Sınıf Kitaplığı'ndaki Zamanlayıcı Sınıflarını Karşılaştırma " - .chm dosyası olarak da kullanılabilir

Spesifik fark System.Timers.Timer, çok iş parçacıklı uygulamalara yönelik olduğu ve bu nedenle SynchronizationObjectözelliği sayesinde diş güvenliğine sahip olduğu halde System.Threading.Timer, ironik olarak kutudan çıktığı gibi güvenli değildir.

Aralığınızın ne kadar küçük olabileceğiyle ilgili olarak ikisi arasında bir fark olduğuna inanmıyorum.


69
Ben bu alıntı aydınlatıcı olduğunu düşünüyorum: "System.Windows.Forms.Timer aksine, System.Timers.Timer sınıfı, varsayılan olarak, ortak dil çalışma zamanı (CLR) iş parçacığı havuzundan alınan bir çalışan iş parçacığı üzerinde zamanlayıcı olay işleyicisini çağıracak . [...] System.Timers.Timer sınıfı bu ikilemle başa çıkmak için kolay bir yol sağlar - genel bir SynchronizingObject özelliğini ortaya koyar.Bu özelliği bir Windows Formunun (veya Windows Formundaki bir denetimin) örneğine ayarlamak Geçen olay işleyicinizdeki kodun SynchronizingObject öğesinin örneklendiği aynı iş parçacığında çalıştığından emin olun. "
mico

7
Threading.Timer'S MSDN makalesinde Konu Güvenliği bölümüne göre , mükemmel iş parçacığı için güvenli ...
Pieter

62
System.Threading.Timer"ironik olarak" System.Threading.Threadve havuzdan elde edilen iplikler kadar güvenli değildir . Bu sınıfların elinizi locktutmaması ve anahtar kelimenin kendisini yönetmemesi, bu sınıfların güvenli olmadığı anlamına gelmez. Siz de System.Threading.Threadthreadsafe olmadığını söyleyebilirsiniz , çünkü tam olarak doğrudur.
Kirk Woll

8
Ayrıca System.Timer.Timer aralığı yalnızca Int32 System.Threading.Timer aralığı Int64
Brent

11
Bu son derece yanıltıcı (en iyi ihtimalle) cevabın kabul edilmesi ve çok yüksek oy kullanılması talihsiz bir durumdur. Cevabın kendisindeki tek maddi ifade yanlıştır. SynchronizingObjectZamanlayıcı nesnenin kendisi evreli yapmaz. Sadece timer olayını işlemek için kodunuzun belirli bir iş parçacığında çağrılmasını sağlar (bu özelliği uygun şekilde ayarlarsanız). Zamanlayıcı nesnesinin , belgelerde açıkça belirtildiği gibi, iş parçacığı açısından güvenli olduğu garanti edilmez . Öte yandan, System.Threading.Timerbir amacı olan , özellikle evreli olarak belgelenmiştir.
Peter Duniho

169

System.Threading.Timerdüz bir zamanlayıcıdır. Bir iş parçacığı havuzu iş parçacığı (işçi havuzundan) geri çağırır.

System.Timers.TimerBir olan System.ComponentModel.Componentbir sarar olduğunu System.Threading.Timerbelli parçacığı üzerinde sevk için kullanılan bazı ek özellikler ve sağlar.

System.Windows.Forms.Timerbunun yerine yerel bir salt HWND iletisini sarar ve bu HWND'ler ileti döngüsünde olayları yükseltmek için Pencere Zamanlayıcılarını kullanır .

Uygulamanızın kullanıcı arayüzü yoksa ve mümkün olan en hafif ve genel amaçlı .Net zamanlayıcıyı istiyorsanız (kendi iş parçacığınızı / sevkıyatınızı bulmaktan mutlu olduğunuz için) System.Threading.Timer, o zaman çerçevede olduğu kadar iyidir.

Sözde 'güvenli değil iplik' ile System.Threading.Timerilgili sorunların ne olduğunu tam olarak açık değilim . Belki de bu soruda sorulduğu gibidir: System.Timers.Timer vs System.Threading.Timer veya belki herkes sadece iş parçacığı güvenliği :

  1. zamanlayıcıları kullanırken yarış koşullarını yazmak kolaydır. Örneğin şu soruya bakın: Zamanlayıcı (Sistem Diş Açma) diş güvenliği

  2. timer etkinliğinizin ilk etkinliği işleme koymadan önce ikinci kez tetikleyebileceği ve sizi geri arayabileceği timer bildirimlerinin tekrar girilmesi . Örneğin şu soruya bakın: System.Threading.Timer ve Monitor kullanarak iş parçacığı için güvenli yürütme


Gerçek System.Timers.Timerbir kullanır System.Threading.Timeriçten. Kaynak koduna bakın .
stomi

120

Jeff Ritcher , " CR Via C # " adlı kitabında , bu zamanlayıcıyı kullanarak Visual Studio'nun tasarım yüzeyinde kullanılmasına izin vererek türetilmiştir . Böylece sadece bir tasarım yüzeyinde bir zamanlayıcı istiyorsanız yararlı olur.System.Timers.TimerSystem.ComponentModel.Component

System.Threading.TimerBir iş parçacığı havuzu iş parçacığında arka plan görevleri için kullanmayı tercih eder .


36
Bir tasarım yüzeyinde kullanılabilir - olması gerektiği anlamına gelmez ve bunu yapmanın zararlı etkileri yoktur. Bu sorunun daha önceki cevabındaki makaleyi okuyan Timers.Timer, Threading.Timer'e çok daha tercih edilir gibi görünüyor.
Stephen Drew

6
Peki, tercih edilen şey bağlama bağlıdır, değil mi? Anladığım kadarıyla, System.Threading.Timer iş parçacığı geri arama iş parçacığı yeni bir iş parçacığı iş parçacığında yürütür. Hangi, sanırım neden mutlaka iş parçacığı için güvenli değil. Tür mantıklı. Yani, teoride, bu işçi sizin için yapacağından, kendi işçi ipliğinizi döndürmenin zahmetli çalışması hakkında endişelenmenize gerek kalmayacaktı. Biraz gülünç derecede faydalı görünüyor.
Finster

6
Kullanmak System.Threading.Timerbir iş parçacığı havuzu kullanmaya veya kendi iş parçacığınızı oluşturmaya benzer. Of Tabii bu sınıflar sizin için senkronizasyonu dokunmayın - en senin işin o! Ne bir iş parçacığı havuzu iş parçacığı, ne kendi iş parçanız, ne de bir zamanlayıcı geri çağırma kilitlemeyi kaldıramaz - hangi nesne ve hangi tarzda ve hangi koşullarda kilitlemeniz gerektiğine dair iyi bir karar gerektirir ve zamanlayıcının iş parçacığı sürümü size en fazla esnekliği sağlar ve ayrıntı düzeyi.
Kirk Woll

2
-1 bu cevap en başından beri özneldir veya düşünülmüştür ve System.Threading.Timer tarafından neden Jeff Ritcher
Brian Ogden

42

Microsoft'tan bununla ilgili bilgiler (bkz . MSDN Hakkında Açıklamalar ):

  • Bir olayı başlatan ve kodu düzenli aralıklarla bir veya daha fazla olay havuzunda yürüten System.Timers.Timer . Sınıf, çok iş parçacıklı bir ortamda sunucu tabanlı veya hizmet bileşeni olarak kullanılmak üzere tasarlanmıştır; kullanıcı arabirimi yoktur ve çalışma zamanında görünmez.
  • Bir iş parçacığı havuzu iş parçacığında düzenli aralıklarla tek bir geri arama yöntemi yürüten System.Threading.Timer . Geri arama yöntemi, zamanlayıcı başlatıldığında tanımlanır ve değiştirilemez. System.Timers.Timer sınıfı gibi, bu sınıf da çok iş parçacıklı bir ortamda sunucu tabanlı veya hizmet bileşeni olarak kullanılmak üzere tasarlanmıştır; kullanıcı arabirimi yoktur ve çalışma zamanında görünmez.
  • System.Windows.Forms.Timer (yalnızca .NET Framework), bir olayı başlatan ve kodu düzenli aralıklarla bir veya daha fazla olay havuzunda yürüten bir Windows Forms bileşeni. Bileşenin kullanıcı arabirimi yoktur ve tek iş parçacıklı bir ortamda kullanılmak üzere tasarlanmıştır; UI iş parçacığında yürütülür.
  • System.Web.UI.Timer (yalnızca .NET Framework), zamanuyumsuz veya eşzamanlı web sayfası geri gönderimlerini düzenli aralıklarla gerçekleştiren bir ASP.NET bileşeni.

System.Timers.Timer.NET Core 1.0 ile kullanımdan kaldırılmış, ancak .NET Core 2.0'da (/ .NET Standard 2.0) yeniden uygulandığından bahsetmek ilginçtir . .NET Standard 2.0 ile amaç, muhtemelen geri gelmesinin nedeni olan .NET Framework'ten geçişin mümkün olduğunca kolay olmasıydı.

Kullanımdan kaldırıldığında, .NET Taşınabilirlik Çözümleyicisi Visual Studio Eklentisi'nin kullanılması önerilir System.Threading.Timer.

Microsoft'un daha System.Threading.Timerönce desteklediği anlaşılıyor System.Timers.Timer.

DÜZENLEME NOT 2018-11-15: Cevabımı .NET Core 1.0 hakkındaki eski bilgiler artık geçerli olmadığından değiştirmeyi seviyorum.



@Taegost, kullanımı da sınırlıdır - MSDN msdn.microsoft.com/en-us/library/… adresine bakın ve platformun kullanılabilirliği ile ilgili açıklamaları okuyun.
astrowalker

@astrowalker - Bunun için teşekkürler, yorumu yaptığım zaman bu cevabın neredeyse hiç detayı yoktu. Şimdi sorguladığım ayrıntıya sahip olduğu için yorumumu sildim.
Taegost

1
System.Timers.Timer artık .NET Standard 2.0 ve .NET Core 2.0 ve üzeri sürümlerde desteklenmektedir. docs.microsoft.com/tr-tr/dotnet/api/system.timers.timer (makalenin sonuna kaydırın)
Lee Grissom


39

Yukarıda belirtilmeyen, sizi yakalayabilecek önemli bir fark System.Timers.Timer, istisnaları sessizce yutmasıdır, oysa System.Threading.Timerdeğil.

Örneğin:

var timer = new System.Timers.Timer { AutoReset = false };
timer.Elapsed += (sender, args) =>
{
    var z = 0;
    var i = 1 / z;
};
timer.Start();

vs

var timer = new System.Threading.Timer(x =>
{
    var z = 0;
    var i = 1 / z;
}, null, 0, Timeout.Infinite);

1
Son zamanlarda Timers.Timer ile bu sorunu vurdum ve çok acı vericiydi ... Threading.Timer ile nasıl yeniden yazabileceğim hakkında herhangi bir fikir? stackoverflow.com/questions/41618324/…
Tez Wingfield

7
Kaynak kodda boş bir yakalama var. Burada System.Timers.Timer kaynak koduna
16'da stomi

Omgsh MS programcıları neden aynı şeyleri gerçekten aynı şekilde yapamıyor?
xmedeko

2
Örnek, bir kişinin istisnaları nasıl yuttuğunu diğerinin nasıl yutmayacağını açıklamaz. Birisi lütfen ayrıntıları doldurabilir mi?
sean

24

MSDN'den kısa bir karşılaştırma buldum

.NET Framework Sınıf Kitaplığı, her biri farklı işlevler sunan Timer adında dört sınıf içerir:

System.Timers.Timer, bir olayı başlatır ve kodu düzenli aralıklarla bir veya daha fazla olay havuzunda yürütür. Sınıf, çok iş parçacıklı bir ortamda sunucu tabanlı veya hizmet bileşeni olarak kullanılmak üzere tasarlanmıştır; kullanıcı arabirimi yoktur ve çalışma zamanında görünmez.

System.Threading.Timer, düzenli aralıklarla bir iş parçacığı havuzu iş parçacığında tek bir geri arama yöntemi yürütür. Geri arama yöntemi, zamanlayıcı başlatıldığında tanımlanır ve değiştirilemez. System.Timers.Timer sınıfı gibi, bu sınıf da çok iş parçacıklı bir ortamda sunucu tabanlı veya hizmet bileşeni olarak kullanılmak üzere tasarlanmıştır; kullanıcı arabirimi yoktur ve çalışma zamanında görünmez.

System.Windows.Forms.Timer, bir olayı başlatan ve kodu düzenli aralıklarla bir veya daha fazla olay havuzunda yürüten bir Windows Forms bileşeni. Bileşenin kullanıcı arabirimi yoktur ve tek iş parçacıklı bir ortamda kullanılmak üzere tasarlanmıştır.

System.Web.UI.Timer, eşzamansız veya eşzamanlı web sayfası geri gönderimlerini düzenli aralıklarla gerçekleştiren bir ASP.NET bileşeni.


1

İki sınıf işlevsel olarak eşdeğerdir, ancak bunun SynchronizingObject ayarını System.Timers.Timeryaparak ISynchronizeInvoke aracılığıyla tüm zamanlayıcı süre sonu geri çağrılarını çağırmak için bir seçeneği vardır . Aksi takdirde, her iki zamanlayıcı iş parçacığı havuzu iş parçacıklarında son kullanma geri çağrılarını çağırır.

Bir System.Timers.TimerWindows Forms tasarım yüzeyine sürüklediğinizde , Visual Studio SynchronizingObject öğesini form nesnesine ayarlar ve bu da tüm süre sonu geri çağrılarının UI iş parçacığında çağrılmasına neden olur.


1

MSDN'den: System.Threading.Timergeri arama yöntemlerini kullanan ve iş parçacığı havuzu iş parçacıkları tarafından sunulan basit, hafif bir zamanlayıcıdır. Windows Forms ile kullanılması önerilmez, çünkü geri çağrıları kullanıcı arabirimi iş parçacığında görülmez. System.Windows.Forms.TimerWindows Forms ile kullanmak için daha iyi bir seçimdir. Sunucu tabanlı zamanlayıcı işlevselliği için, System.Timers.Timeretkinlikleri artıran ve ek özelliklere sahip olan kullanmayı düşünebilirsiniz .

Kaynak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.