私は最近の可能なタイマーのいくつかをチェックアウトし、されているSystem.Threading.Timer
とSystem.Timers.Timer
(彼らは、スレッドプールをサポートするので)私に入用に見えるものです。
私はゲームを作っており、すべてのタイプのイベントを、異なる間隔などで使用する予定です。
どれが一番いいですか?
私は最近の可能なタイマーのいくつかをチェックアウトし、されているSystem.Threading.Timer
とSystem.Timers.Timer
(彼らは、スレッドプールをサポートするので)私に入用に見えるものです。
私はゲームを作っており、すべてのタイプのイベントを、異なる間隔などで使用する予定です。
どれが一番いいですか?
回答:
この記事はかなり包括的な説明を提供します:
「.NET Frameworkクラスライブラリのタイマークラスの比較」-.chmファイルとしても利用可能
具体的な違いSystem.Timers.Timer
は、マルチスレッドアプリケーションを対象としているためSynchronizationObject
、そのプロパティを介してスレッドセーフであるのに対して、System.Threading.Timer
皮肉なことに、最初からスレッドセーフではないようです。
あなたの間隔がどれほど小さいかということに関係しているので、私は2つの間に違いがあるとは信じていません。
System.Threading.Timer
「皮肉なことに」スレッドセーフではなくSystem.Threading.Thread
、プールを通じて取得されたスレッドも同様です。これらのクラスがあなたの手を握らず、lock
キーワード自体の使用を管理しているからといって、これらのクラスがスレッドセーフではないという意味ではありません。あなたにも言うかもしれないSystem.Threading.Thread
、それはまさに真のようなので、スレッドセーフではありません。
SynchronizingObject
タイマーオブジェクト自体はスレッドセーフではありません。タイマーイベントを処理するコードが特定のスレッドで呼び出されることを確認するだけです(そのプロパティを適切に設定した場合)。ドキュメントに明記されているように、タイマーオブジェクト自体はスレッドセーフであるとは限りません。一方、System.Threading.Timer
オブジェクトはスレッドセーフであると明確に文書化されています。
System.Threading.Timer
単純なタイマーです。スレッドプールスレッドで(ワーカープールから)コールバックします。
System.Timers.Timer
あるSystem.ComponentModel.Component
ラップことSystem.Threading.Timer
、及び特定のスレッドにディスパッチするために使用されるいくつかの追加機能を提供します。
System.Windows.Forms.Timer
代わりに、ネイティブメッセージのみのHWNDをラップし、ウィンドウタイマーを使用します。をして、そのHWNDメッセージループでイベントを発生させます。
アプリにUIがなく、可能な限り最も軽量で汎用的な.Netタイマーが必要な場合(独自のスレッド化/ディスパッチを理解して満足しているため) System.Threading.Timer
、フレームワークと同じくらい優れています。
想定される「スレッドセーフではない」問題が何であるかについては、完全には明確ではありませんSystem.Threading.Timer
。おそらくそれはこの質問で尋ねられたものと同じです:System.Timers.TimerとSystem.Threading.Timerのスレッドセーフ、またはおそらく誰もがそれを意味するだけです:
タイマーを使用している場合は、競合状態を簡単に記述できます。たとえば、この質問を参照してください: タイマー(System.Threading)スレッドセーフティ
あなたのタイマーイベントがトリガとバックあなたを呼び出すことができますタイマー通知のリエントラント秒あなたが処理を完了するまでの時間最初のイベントを。たとえば、この質問を参照してください:System.Threading.TimerとMonitorを使用したスレッドセーフな実行
彼の著書「CLR Via C#」では、Jeff Ritcherはの使用を推奨していませんSystem.Timers.Timer
。このタイマーはから派生しSystem.ComponentModel.Component
、Visual Studioのデザイン画面で使用できるようにします。そのため、デザインサーフェイスにタイマーが必要な場合にのみ役立ちます。
彼はSystem.Threading.Timer
スレッドプールスレッドのバックグラウンドタスクに使用することを好みます。
System.Threading.Timer
は、スレッドプールの使用や独自のスレッドの作成に似ています。 うちもちろんこれらのクラスはあなたのための同期を処理しません -あなたの仕事ですもの!スレッドプールスレッド、独自のスレッド、タイマーコールバックのいずれもロックを処理しません-どのオブジェクトで、どのような方法でどのような状況でロックする必要があるかは、適切な判断が必要であり、タイマーのスレッドバージョンは最も柔軟性が高く、粒度。
これに関するマイクロソフトからの情報(MSDNの備考を参照):
- System.Timers.Timerは、イベントを発生させ、1つ以上のイベントシンクで定期的にコードを実行します。このクラスは、マルチスレッド環境でサーバーベースまたはサービスコンポーネントとして使用するためのものです。ユーザーインターフェイスがなく、実行時に表示されません。
- System.Threading.Timerは、スレッドプールスレッドで単一のコールバックメソッドを定期的に実行します。コールバックメソッドは、タイマーがインスタンス化されたときに定義され、変更できません。System.Timers.Timerクラスと同様に、このクラスは、マルチスレッド環境でサーバーベースまたはサービスコンポーネントとして使用するためのものです。ユーザーインターフェイスがなく、実行時に表示されません。
- System.Windows.Forms.Timer (.NET Frameworkのみ)。イベントを発生させ、1つ以上のイベントシンクのコードを定期的に実行するWindowsフォームコンポーネントです。このコンポーネントにはユーザーインターフェイスがなく、シングルスレッド環境で使用するように設計されています。UIスレッドで実行されます。
- System.Web.UI.Timer (.NET Frameworkのみ)。非同期または同期のWebページポストバックを定期的に実行するASP.NETコンポーネント。
それは興味深いことです System.Timers.Timer
.NET Core 1.0では非推奨でしたが、.NET Core 2.0(/ .NET Standard 2.0)で再び実装された。.NET Standard 2.0の目標は、.NET Frameworkからの切り替えが可能な限り簡単であるということでした。これが、おそらくそれが戻ってきた理由です。
非推奨の場合、.NET Portability Analyzer Visual Studio Add-Inを使用することをお勧めしますSystem.Threading.Timer
ことを。
System.Threading.Timer
以前はマイクロソフトが支持していたようですSystem.Timers.Timer
。
ノートの編集2018-11-15: .NET Core 1.0に関する古い情報が無効になったため、回答を変更します。
上記で説明されていない重要な違いの1つは、System.Timers.Timer
例外を黙って飲み込んでしまうのですが、System.Threading.Timer
そうではありません。
例えば:
var timer = new System.Timers.Timer { AutoReset = false };
timer.Elapsed += (sender, args) =>
{
var z = 0;
var i = 1 / z;
};
timer.Start();
対
var timer = new System.Threading.Timer(x =>
{
var z = 0;
var i = 1 / z;
}, null, 0, Timeout.Infinite);
MSDNから短い比較を見つけました
.NET Frameworkクラスライブラリには、Timerという名前の4つのクラスが含まれ、それぞれが異なる機能を提供します。
System.Timers.Timer
、イベントを発生させ、1つ以上のイベントシンクのコードを定期的に実行します。このクラスは、マルチスレッド環境でサーバーベースまたはサービスコンポーネントとして使用するためのものです。ユーザーインターフェイスがなく、実行時に表示されません。
System.Threading.Timer
、スレッドプールスレッドで単一のコールバックメソッドを定期的に実行します。コールバックメソッドは、タイマーがインスタンス化されたときに定義され、変更できません。System.Timers.Timerクラスと同様に、このクラスは、マルチスレッド環境でサーバーベースまたはサービスコンポーネントとして使用するためのものです。ユーザーインターフェイスがなく、実行時に表示されません。
System.Windows.Forms.Timer
、イベントを発生させ、1つ以上のイベントシンクで定期的にコードを実行するWindowsフォームコンポーネント。このコンポーネントにはユーザーインターフェースがなく、シングルスレッド環境で使用するように設計されています。
System.Web.UI.Timer
、定期的間隔で非同期または同期のWebページポストバックを実行するASP.NETコンポーネント。
2つのクラスは機能的には同等ですSystem.Timers.Timer
が、SynchronizingObjectを設定することにより、ISynchronizeInvokeを介してすべてのタイマー期限切れコールバックを呼び出すオプションがあります。それ以外の場合、両方のタイマーがスレッドプールスレッドで期限切れコールバックを呼び出します。
をSystem.Timers.Timer
Windowsフォームデザインサーフェイスにドラッグすると、Visual StudioはSynchronizingObjectをフォームオブジェクトに設定します。これにより、すべての有効期限コールバックがUIスレッドで呼び出されます。