Following a suggestion from svick I created a little class whose purpose is to run Tasks sequentially, that is, it schedules them on the ThreadPool but it ensures they execute one after the other, in the order they were submitted. It looks like this:
class SequentialTaskRunner<TResult> where TResult : new() {
public Task<TResult> Run(Func<TResult> func) {
var result = RunInternal(func, m_previous);
m_previous = result;
return result;
}
async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous) {
await previous;
return await Task.Run(func);
}
Task<TResult> m_previous = Task.FromResult(new TResult());
}
Now, the problem I have is that if func() throws an exception, then every subsequent invocation of Run() will also return that exception, and it's impossible to run new tasks. I've tried to change RunInternal like so:
async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous) {
if (previous.Exception == null) {
await previous;
}
return await Task.Run(func);
}
But this does not work reliably; if tasks are submitted quickly, the failure of one can still cause several to return the same exception. I am confused as to why and would like an explanation. I'm just getting started with async/await btw.