2013-01-14 8 views
5

に待望することができ、非同期カウンタ、SendImageなど私は、このようなSendTextなど、いくつかの非同期メソッドを持っている接続クラスを持っている

接続クラスは、Disconnectメソッドを持っており、それが呼び出されたとき、私は注意する必要がありますすべての非同期メソッドの実行が完了する前に、クラスの内部状態の変更を開始しないようにします。

これを実現する良い方法は、実行中の操作数の合計を単純に保持してから、Disconnecting = trueを設定してカウントが0に達するまで待つだけです

私は非同期操作を開始したときにその後、私は

refCounter.Increment(); 

それを行うことができ、この

class ReferenceCounter 
{ 
    void Increment(); 

    void Decrement(); 

    async Task WaitForCounterToReachZero(); 
} 

の線に沿って何かを考えています

refCounter.Decrement(); 

とDisconnectメソッドの内部

disconnecting = true; 
taskCancellationSource.Cancel(); 
await refCounter.WaitForCounterToReachZero(); 
Cleanup(); 

は、このような.NETのクラスで構築された任意のはあります終了しますか?

さらに重要なことに、これを行うにはより良い方法がありますか?

それは同期コードだった場合、それは私がちょうど同じことを行いCountdownEventクラスに建てられたが、それは何の非同期待機メソッドを持っていないも、それはすべてのイベントを持っていない、

lock (thisLock) 
{ 
    while (counter > 0) 
     Monitor.Wait(thisLock); 
} 

ような単純なものでしょうだから私はブロックしなければならないだろう。

答えて

4

さて、あなたはそれが0、あなたはこのような何かを行うことができ作る再び後にインクリメントすることは決してないだろうと仮定すると:

public class Latch 
{ 
    private int count = 0; 
    private readonly TaskCompletionSource<object> tcs = 
     new TaskCompletionSource<object>(); 

    public void Increment() 
    { 
     Interlocked.Increment(ref count); 
    } 

    public void Decrement() 
    { 
     if (Interlocked.Decrement(ref count) == 0) 
     { 
      tcs.TrySetValue(null); 
     } 
    } 

    public Task Task { get { return tcs.Task; } } 
} 

は、その後、あなたが someLatch.Taskを待つことができます。また、あなたは自身がawaitableラッチを作ることができる: - あなたはそれが何をしたいと思うものを考える

public TaskAwaiter GetAwaiter() 
{ 
    return tcs.Task.GetAwaiter(); 
} 

あなたはおそらく、あなたが警戒する方法を検討すべきであるthuogh側面「カウント0まで取得した後に上昇します」 。 (上記のコードでは、TCSの値が設定されると、すぐに完了するようになります)

+0

これは、私が心に留めていたことをうまく実装した素晴らしい方法です。 _disconnectingブールがそれ以上の操作を妨げるので、0になった後にカウントが上昇することについて心配する必要はありません。それはさておき、これがこのようなシナリオを処理する良い方法だと思いますか?私の懸念は、そのようなクラスがフレームワークに存在しない理由は、そのようなことが嫌になるからです。あなたは同じような状況で自分自身を見つけましたか? – NoPyGod

+2

@NoPyGod:カウントが本当に必要かどうかは明らかではありません。非同期メソッドのロードについて話します。もしそうなら、 'Task.WhenAll'はあなたの友人です。あなたは未解決のタスクのプールを保つことができ、すべて完了するまで待つ 'Task.WhenAll'を待つだけです。 –

+0

私はそれを行うことができますが、非同期メソッド本体の中には返されるタスクにアクセスする方法がありません。あなたが提案していることを達成するために、私は未処理タスクのプールに追加できるTaskを返す内部メソッドをラップする必要があります。これは、私が示唆しているものよりも挑戦されたようですが、それがこれらのような状況のために推奨される練習であれば、私はそうすることを好むでしょう。あなたの明らかな専門知識があれば、私はあなたの意見に非常に興味があります。 – NoPyGod

関連する問題