/// <summary> /// Creates an asynchronous Task object that executes the given plugin on a background thread and /// invokes all other callbacks (success, failure, etc.) on the UI thread. /// </summary> /// <param name="cancellationToken"></param> /// <param name="plugin"></param> /// <param name="pluginRunner"></param> /// <returns></returns> private Task <bool> RunPluginSync(CancellationToken cancellationToken, IPlugin plugin, ExecutePluginHandler pluginRunner) { var task = new TaskBuilder() .OnThread(_callbackScheduler) .CancelWith(cancellationToken) .BeforeStart(delegate { var progressProvider = _pluginRepository.GetProgressProvider(plugin); progressProvider.Updated -= ProgressProviderOnUpdated; progressProvider.Updated += ProgressProviderOnUpdated; progressProvider.Reset(); progressProvider.Start(); }) .DoWork(delegate(IThreadInvoker invoker, CancellationToken token) { pluginRunner(token); }) .Fail(delegate(ExceptionEventArgs args) { var progressProvider = _pluginRepository.GetProgressProvider(plugin); if (args.Exception is OperationCanceledException) { progressProvider.Cancel(); } else { progressProvider.Error(args.Exception); HandleUnhandledException(args.Exception); } }) .Succeed(delegate { var progressProvider = _pluginRepository.GetProgressProvider(plugin); if (cancellationToken.IsCancellationRequested) { progressProvider.Cancel(); } else { progressProvider.Succeed(); } }) .Build() ; task.RunSynchronously(); return(task); }