8

いつでも、実行時間の長い操作を必要とするメソッド呼び出しを受け取ることができます。

これらの方法にはいくつかあります。これらはリソースを共有するため、同時に実行しないことが重要です。それぞれを順番に実行する必要があります。

通常、私は単純に順番に呼び出しを行います:

var result1 = await Foo1Async();
var result2 = await Foo2Async();

ただし、この場合、私へのメソッド呼び出しは非同期です。

void Bar1()
{
    var result = await Foo1Async();
    // ...
}

void Bar2()
{
    var result = await Foo2Async();
    // ...
}

を使用する必要があると思いますがTask.ContinueWith、これを思いつきました:

readonly object syncLock = new Object();

private Task currentOperationTask = TaskUtilities.CompletedTask;
public Task<TResult> EnqueueOperation<TResult>(Func<Task<TResult>> continuationFunction)
{
    lock (this.syncLock)
    {
        var operation = this.currentOperationTask.ContinueWith(predecessor => continuationFunction()).Unwrap();
        this.currentOperationTask = operation;
        return operation;
    }
}

そして、私はそれを次のように使用します:

void Bar1()
{
    var result = await EnqueueOperation(() => Foo1Async());
    // ...
}

void Bar2()
{
    var result = await EnqueueOperation(() => Foo2Async());
    // ...
}

これは、この問題にアプローチする正しい方法ですか? 注意すべき落とし穴はありますか?

4

1 に答える 1

1

あなたのコードは問題なく動作します。これは問題を解決する合理的な方法だと思います。

これを行うためのより簡単な方法は、AsyncLockNito AsyncExから使用することです:

private readonly AsyncLock asyncLock = new AsyncLock();

public async Task<TResult> EnqueueOperation<TResult>(
    Func<Task<TResult>> continuationFunction)
{
    using (await asyncLock.LockAsync())
    {
        return await continuationFunction();
    }
}
于 2013-07-08T01:39:07.807 に答える