private static Task <object> AskEx(ICanTell self, Func <IActorRef, object> messageFactory, IActorRefProvider provider, TimeSpan?timeout, CancellationToken cancellationToken) { var result = new TaskCompletionSource <object>(); CancellationTokenSource timeoutCancellation = null; timeout = timeout ?? provider.Settings.AskTimeout; List <CancellationTokenRegistration> ctrList = new List <CancellationTokenRegistration>(2); if (timeout != System.Threading.Timeout.InfiniteTimeSpan && timeout.Value > default(TimeSpan)) { timeoutCancellation = new CancellationTokenSource(); ctrList.Add(timeoutCancellation.Token.Register(() => result.TrySetCanceled())); timeoutCancellation.CancelAfter(timeout.Value); } if (cancellationToken.CanBeCanceled) { ctrList.Add(cancellationToken.Register(() => result.TrySetCanceled())); } //create a new tempcontainer path ActorPath path = provider.TempPath(); //callback to unregister from tempcontainer Action unregister = () => { // cancelling timeout (if any) in order to prevent memory leaks // (a reference to 'result' variable in CancellationToken's callback) if (timeoutCancellation != null) { timeoutCancellation.Cancel(); timeoutCancellation.Dispose(); } for (var i = 0; i < ctrList.Count; i++) { ctrList[i].Dispose(); } provider.UnregisterTempActor(path); }; var future = new FutureActorRef(result, unregister, path); //The future actor needs to be registered in the temp container provider.RegisterTempActor(future, path); self.Tell(messageFactory(future), future); return(result.Task); }
public AskRefs(FutureActorRef futureRef, TaskCompletionSource <object> completionSource) { FutureActorRef = futureRef; CompletionSource = completionSource; }