2013-06-29 12 views
11

イベントドリブンロジックを備えたMMOゲームサーバーでC#async \ awaitを使用することを考えています。既知の期間で何千ものエンティティが何らかの作業を行っていると仮定しましょう。だから私はすべての私のゲームオブジェクトのためにTime.Delay()を呼びたいと思います。 (これは、すべてのゲームオブジェクトを呼び出すUpdate()と共通の無限ループに対する反対のアプローチです)Task.Delay()の使用には何が必要ですか?

Task.Delay()はどのように実装されていますか? タイマーを使用していますか?システムリソースに重いですか?

Task.Delay()の呼び出しを同時に何千も発生させることはできますか?次のように

+4

@ColeJohnson 'Thread.Sleep'は' async'ではないので、 –

+0

そしてTask.Delayは?それは意味をなさない。スレッドを遅延させたい場合は、今すぐ停止したいスレッドを生成しないようにします。 –

+0

@Coleこれは、スレッドを再開するまでしばらく待つようにすることです。ポイントはスレッドを遅らせることではありません。 –

答えて

17

Task.Delayが実装されています。

public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken) 
{ 
    //error checking 
    Task.DelayPromise delayPromise = new Task.DelayPromise(cancellationToken); 
    if (cancellationToken.CanBeCanceled) 
    delayPromise.Registration = cancellationToken.InternalRegisterWithoutEC((Action<object>) (state => ((Task.DelayPromise) state).Complete()), (object) delayPromise); 
    if (millisecondsDelay != -1) 
    { 
    delayPromise.Timer = new Timer((TimerCallback) (state => ((Task.DelayPromise) state).Complete()), (object) delayPromise, millisecondsDelay, -1); 
    delayPromise.Timer.KeepRootedWhileScheduled(); 
    } 
    return (Task) delayPromise; 
} 

それは間違いなく、タイマーを使用しています。それらはDelayPromiseというクラスで使用されています。

private sealed class DelayPromise : Task<VoidTaskResult> 
{ 
    internal readonly CancellationToken Token; 
    internal CancellationTokenRegistration Registration; 
    internal Timer Timer; 

    internal DelayPromise(CancellationToken token) 
    { 
    this.Token = token; 
    } 

    internal void Complete() 
    { 
    if (!(this.Token.IsCancellationRequested ? this.TrySetCanceled(this.Token) : this.TrySetResult(new VoidTaskResult()))) 
     return; 
    if (this.Timer != null) 
     this.Timer.Dispose(); 
    this.Registration.Dispose(); 
    } 
} 

タイマーを使用していますが、私には心配していないようです。タイマーは完全なメソッドを呼び出すだけで、キャンセルされた場合はチェックし、キャンセルする場合はキャンセルします。それ以外の場合は結果を返します。それは私にとってはうまくいくようです。

+1

私は実際に各遅延に対して新しいタイマーオブジェクトを作成することに驚いています –

+0

MSDNのドキュメントにあるように、「System.Threading.Timerは、コールバックメソッドを使用するシンプルで軽量なタイマーで、スレッドプールスレッドによって処理されます。」私にとっては、 –

+0

Sleep()とタイマー呼び出しの間に選択肢がある場合、いくつかの開発者はスレッド間通信とコンテキスト依存スレッドの追加が必要であると主張しているようですが、 –

関連する問題