I'm attempting to programmatically chain asynchronous operations in C#4, such as Writes to a given Stream object. I originally did this "manually", hooking callbacks from one operation to the next, but I thought I'd try the .NET 4 Task Parallel Library to save myself the trouble of re-inventing the concurrent wheel.
To start with, I wrap my async calls in Tasks like so:
public static Task CreateWriteTask(Stream stream, byte[] data)
{
return Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, data, 0, data.Length, null);
}
Continuations have made chaining synchronous operations very easy (if you'll excuse the unfortunate method name):
public static Task ChainFlush(Stream stream, Task precedingTask)
{
return precedingTask.ContinueWith(x => stream.Flush());
}
But there is no version of the Task.ContinueWith
method that accepts an async operation in the same way as TaskFactory.FromAsync
.
So, assuming that I persist with using the TPL, what I'm looking for the correct implementation of this method:
public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask)
{
//?
}
My best idea so far is to chain the creation of the new write task, then use the Unwrap extension method to turn Task<Task>
back into Task
:
public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask)
{
return precedingTask.ContinueWith(x => CreateWriteTask(stream, data)).Unwrap();
}
As far as I understand it, this is an unfortunate consequence of not being in control over when a task gets started. Since you never know when a task gets started, there can't be an overload like
precedingTask.ContinueWith(Task nextTask)
because once created, it might already be started when you get to 'ContinueWith'. Besides, it would also make a mess of types. What should be the type here:
precedingTask<T>.ContinueWith(Task<..what?..> nextTask)
preceding returns a T, so next takes what and returns what? :) This could be solved with closures though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With