I\'ve got the following scenario, which I think might be quite common:
There is a task (a UI command handler) which can complete either synchronously or asy
Here is a solution that is worse on every aspect compared to the accepted answer, except from being thread-safe (which is not a requirement of the question). Disadvantages:
executeOnCurrentContext configuration effects all lambdas (it's not a per-lambda configuration).This solution uses as processing engine an ActionBlock from the TPL Dataflow library.
public class AsyncOp
{
private readonly ActionBlock>> _actionBlock;
public AsyncOp(bool executeOnCurrentContext = false)
{
var options = new ExecutionDataflowBlockOptions();
if (executeOnCurrentContext)
options.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
_actionBlock = new ActionBlock>>(async taskTask =>
{
try
{
taskTask.RunSynchronously();
await await taskTask;
}
catch { } // Ignore exceptions
}, options);
}
public Task RunAsync(Func> taskFactory)
{
var taskTask = new Task>(taskFactory);
if (!_actionBlock.Post(taskTask))
throw new InvalidOperationException("Not accepted"); // Should never happen
return taskTask.Unwrap();
}
}