I've got an application with multiple Dispatcher
s (aka GUI threads, aka message pumps) to ensure that a slow, unresponsive portion of the GUI runs without affecting the rest of the application too heavily. I also use Task
a lot.
Currently I've got code that conditionally runs an Action
on a TaskScheduler
or a Dispatcher
and then returns a Task
either directly or by manually creating one using TaskCompletionSource
. However, this split personality design makes dealing with cancellation, exceptions etc. all much more complicated than I'd like. I want to use Task
s everywhere and DispatcherOperation
s nowhere. To do that I need to schedule tasks on dispatchers - but how?
How can I get a TaskScheduler
for any given Dispatcher
?
Edit: After the discussion below, I settled on the following implementation:
public static Task<TaskScheduler> GetScheduler(Dispatcher d) {
var schedulerResult = new TaskCompletionSource<TaskScheduler>();
d.BeginInvoke(() =>
schedulerResult.SetResult(
TaskScheduler.FromCurrentSynchronizationContext()));
return schedulerResult.Task;
}
Aborted
event! The only remaining downside is that the task scheduler is created asynchronously; i.e. that you have to wait to schedule tasks until the dispachter has run the invocation (not a major issue, since you canContinueWith
, but it's a little unhandy) – Impress