8
At any time, I can receive a method call that will require a long-running operation to satisfy.
There are several of these methods. Because they share a resource, it's important that they don't run concurrently - each should run in sequence.
Normally, I'd simply make the calls in sequence:
var result1 = await Foo1Async();
var result2 = await Foo2Async();
However, in this case, the method calls to me are asynchronous:
void Bar1()
{
var result = await Foo1Async();
// ...
}
void Bar2()
{
var result = await Foo2Async();
// ...
}
I think I need to use Task.ContinueWith, and have come up with this:
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;
}
}
And I use it like this:
void Bar1()
{
var result = await EnqueueOperation(() => Foo1Async());
// ...
}
void Bar2()
{
var result = await EnqueueOperation(() => Foo2Async());
// ...
}
Is this the right way to approach this problem? Are there any pitfalls I should be aware of?