protected void Execute<TTask>(NativeActivityContext context, CancellationTokenSource cts, TTask resultTask, Action<NativeActivityContext> postExecute) where TTask : Task { if (resultTask.IsCompleted) postExecute(context); else { IActivityContext activityContext = context.GetActivityContext(); taskCompletionNoPersistHandle.Get(context).Enter(context); cancellationTokenSource.Set(context, cts); Bookmark bookmark = context.CreateBookmark(BookmarkResumptionCallback); // continuations don't use cts, the main task is already completed, we can't cancel it resultTask .ContinueWith((_resultTask) => activityContext.ResumeBookmarkThroughHostAsync(bookmark, postExecute, TimeSpan.MaxValue), TaskContinuationOptions.ExecuteSynchronously).Unwrap() // TODO how to handle exception properly? // AsyncCodeActivity has an AsyncOperationContext and it can call Abort on that context directly, but we are left alone now, // we must schedule an Abort through the host, because NativeActivityContext is already disposed now .ContinueWith((_resumeBookmarkTask) => activityContext.AbortThroughHostAsync(_resumeBookmarkTask.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously).Unwrap() .ContinueWith((_abortWorkflowInstanceTask) => { var ignored = _abortWorkflowInstanceTask.Exception; }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously); } }