/// <summary> /// Execute a command and wait for responses from multiple nodes. /// </summary> /// <typeparam name="TResponseFrame">The expected response type</typeparam> /// <param name="frame">The frame to send.</param> /// <param name="callback">This will be called when a response is recieved within the timeout period.</param> /// <param name="timeout">The amount of time to wait before responses will be ignored</param> public async Task ExecuteMultiQueryAsync <TResponseFrame>(CommandFrameContent frame, Action <TResponseFrame> callback, TimeSpan timeout) where TResponseFrame : CommandResponseFrameContent { frame.FrameId = GetNextFrameId(); /* Make sure callback is in this context */ SynchronizationContext context = SynchronizationContext.Current; var callbackProxy = new Action <CommandResponseFrameContent>(callbackFrame => { if (context == null) { callback((TResponseFrame)callbackFrame); } else { context.Post(state => callback((TResponseFrame)callbackFrame), null); } }); ExecuteCallbacks.AddOrUpdate(frame.FrameId, b => callbackProxy, (b, source) => callbackProxy); await ExecuteAsync(frame); await Task.Delay(timeout); Action <CommandResponseFrameContent> action; ExecuteCallbacks.TryRemove(frame.FrameId, out action); }
/// <summary> /// Send a frame to this node and wait for a response. /// </summary> /// <typeparam name="TResponseFrame">The expected response type</typeparam> /// <param name="frame">The frame to send</param> /// <param name="timeout">Timeout</param> /// <returns>The response frame</returns> public async Task <TResponseFrame> ExecuteQueryAsync <TResponseFrame>(CommandFrameContent frame, TimeSpan timeout, CancellationToken cancellationToken) where TResponseFrame : CommandResponseFrameContent { frame.FrameId = GetNextFrameId(); var delayCancellationTokenSource = new CancellationTokenSource(); Task delayTask = Task.Delay(timeout, delayCancellationTokenSource.Token); TaskCompletionSource <CommandResponseFrameContent> taskCompletionSource = ExecuteTaskCompletionSources.AddOrUpdate(frame.FrameId, b => new TaskCompletionSource <CommandResponseFrameContent>(), (b, source) => new TaskCompletionSource <CommandResponseFrameContent>()); await ExecuteAsync(frame, cancellationToken); if (await Task.WhenAny(taskCompletionSource.Task, delayTask) == taskCompletionSource.Task) { delayCancellationTokenSource.Cancel(); return(await taskCompletionSource.Task as TResponseFrame); } throw new TimeoutException(); }
/// <summary> /// Send a frame to this node and wait for a response using a default timeout. /// </summary> /// <typeparam name="TResponseFrame">The expected response type</typeparam> /// <param name="frame">The frame to send</param> /// <param name="cancellationToken">Used to cancel the operation</param> /// <returns>The response frame</returns> public Task <TResponseFrame> ExecuteQueryAsync <TResponseFrame>(CommandFrameContent frame, CancellationToken cancellationToken) where TResponseFrame : CommandResponseFrameContent { return(ExecuteQueryAsync <TResponseFrame>(frame, DefaultRemoteQueryTimeout, cancellationToken)); }
/// <summary> /// Send a frame to this node and wait for a response using a default timeout. /// </summary> /// <typeparam name="TResponseFrame">The expected response type</typeparam> /// <param name="frame">The frame to send</param> /// <returns>The response frame</returns> public Task <TResponseFrame> ExecuteQueryAsync <TResponseFrame>(CommandFrameContent frame) where TResponseFrame : CommandResponseFrameContent { return(ExecuteQueryAsync <TResponseFrame>(frame, CancellationToken.None)); }
/// <summary> /// Send a frame to this node and wait for a response. /// </summary> /// <typeparam name="TResponseFrame">The expected response type</typeparam> /// <param name="frame">The frame to send</param> /// <param name="timeout">Timeout</param> /// <returns>The response frame</returns> public async Task <TResponseFrame> ExecuteQueryAsync <TResponseFrame>(CommandFrameContent frame, TimeSpan timeout) where TResponseFrame : CommandResponseFrameContent { return(await ExecuteQueryAsync <TResponseFrame>(frame, timeout, CancellationToken.None)); }