private async Task <ITaskResult> TryWaitForResultAsync( ServiceId serviceId, MethodId routineMethodId, string intentId, TimeSpan?waitTime) { var cts = new CancellationTokenSource(); var completionSink = new TaskCompletionSource <ITaskResult>(); var trackingToken = _routineCompletionNotifier.NotifyOnCompletion( serviceId, routineMethodId, intentId, completionSink, cts.Token); ITaskResult result; try { result = await completionSink.WithTimeout(waitTime).Task .ContinueWith(t => t.IsCanceled ? null : t.Result); } catch (TaskCanceledException) { result = null; } finally { cts.Cancel(); _routineCompletionNotifier.StopTracking(trackingToken); } return(result); }
/// <remarks> /// Fire and forget mode (async void). /// </remarks> public async void ExecuteAndAwaitInBackground(ExecuteRoutineIntent intent, Task proxyTask) { // TODO: exception handling var result = await _singleMethodInvoker.InvokeAsync(intent); if (result.Outcome == InvocationOutcome.Complete) { proxyTask.TrySetResult(result.Result); } else { var tcs = new TaskCompletionSource <ITaskResult>(); _routineCompletionNotifier.NotifyOnCompletion(intent.Service, intent.Method, intent.Id, tcs, default); var taskResult = await tcs.Task; proxyTask.TrySetResult(taskResult); } }