7

SendText、SendImage などのいくつかの非同期メソッドを持つ接続クラスがあります。

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

これを達成するための良い方法は、実行中の操作の現在の合計数を維持することだと思います。その後、切断したい場合は、単純に Disconnecting = true を設定し、カウントが 0 になるのを待ちます。

私はこれに沿って何かを考えています

class ReferenceCounter
{
    void Increment();

    void Decrement();

    async Task WaitForCounterToReachZero();
}

次に、非同期操作が開始されたときにできること

refCounter.Increment();

終わったら

refCounter.Decrement();

および切断メソッド内

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

このような組み込みの .NET クラスはありますか?

または、私にとってもっと重要なのは、これを行うためのより良い方法はありますか?

同期コードの場合、次のように簡単になります

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

同じことを行う組み込みの CountdownEvent クラスを見つけましたが、非同期の Wait メソッドもイベントもないため、ブロックする必要があります。

4

1 に答える 1

6

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。または、ラッチ自体を待機可能にすることもできます。

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

おそらく、「カウントが0になった後にカウントが上がる」という側面をどのようにガードするかを検討する必要があります-何をしたいかを考えてください。(上記のコードでは、TCS の値が設定されると、さらに awaits がすぐに完了します。)

于 2013-01-14T06:46:30.233 に答える