public static Task WaitAsync(this AsyncCountdownEvent countdownEvent, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.WhenAny(countdownEvent.WaitAsync(), cancellationToken.AsTask())); }
/// <summary> /// Helper method to begin processing user provided image/video data. Starts the initial component control, input and output ports and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="initialComponent">The first component in your pipeline.</param> /// <param name="cancellationToken">A CancellationToken to observe while waiting for a task to complete.</param> /// <returns>The awaitable Task.</returns> public async Task ProcessAsync(IDownstreamComponent initialComponent, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(initialComponent); initialComponent.Control.Start(); initialComponent.Inputs[0].Start(); var tasks = new List <Task>(); tasks.Add(initialComponent.Inputs[0].Trigger.Task); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); component.ForceStopProcessing = false; foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.Start(); tasks.Add(port.Trigger.Task); } } } // Get buffer from input port pool var inputBuffer = initialComponent.Inputs[0].BufferPool.Queue.GetBuffer(); if (inputBuffer.CheckState()) { initialComponent.Inputs[0].SendBuffer(inputBuffer); } if (cancellationToken == CancellationToken.None) { await Task.WhenAll(tasks).ConfigureAwait(false); } else { await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()).ConfigureAwait(false); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks).ConfigureAwait(false); } // Cleanup each downstream component. foreach (var component in handlerComponents) { foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.DisablePort(); } } component.CleanPortPools(); component.DisableConnections(); } }
public static Task <TResult> AsCancelable <TResult>(this Task <TResult> originalTask, CancellationToken cancellationToken) { return(Task.WhenAny(originalTask, cancellationToken.AsTask <TResult>()).Unwrap()); }
public static Task WaitAsync(this AsyncManualResetEvent resetEvent, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.WhenAny(resetEvent.WaitAsync(), cancellationToken.AsTask())); }
/// <summary> /// Helper method to begin processing image data. Starts the Camera port and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="cameraPort">The camera port which image data is coming from.</param> /// <param name="cancellationToken">A CancellationToken to observe while waiting for a task to complete.</param> /// <returns>The awaitable Task.</returns> public async Task ProcessAsync(OutputPortBase cameraPort, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(); if (handlerComponents.Count == 0) { await this.ProcessRawAsync(cameraPort, cancellationToken); return; } List <Task> tasks = new List <Task>(); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); component.ForceStopProcessing = false; foreach (var port in component.ProcessingPorts.Values) { port.Trigger = false; if (port.ConnectedReference == null) { tasks.Add(Task.Run(async() => { while (!port.Trigger) { await Task.Delay(50).ConfigureAwait(false); } }, cancellationToken)); port.Start(); } } } // We now begin capturing on the camera, processing will commence based on the pipeline configured. this.StartCapture(cameraPort); if (cancellationToken == CancellationToken.None) { await Task.WhenAll(tasks).ConfigureAwait(false); } else { await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()).ConfigureAwait(false); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks).ConfigureAwait(false); } // Disable the image encoder output port. foreach (var component in handlerComponents) { foreach (var port in component.ProcessingPorts.Values) { // Apply any final processing on each component port.Handler?.PostProcess(); if (port.ConnectedReference == null) { port.DisablePort(); } } component.CleanPortPools(); component.DisableConnections(); } this.StopCapture(cameraPort); }
public static async Task <T> WithCancellation <T>(this Task <T> task, CancellationToken token, bool configureAwait = true) { return(await await Task.WhenAny(task, token.AsTask <T>()).ConfigureAwait(configureAwait)); }
/// <summary> /// Helper method to begin processing image data. Starts the Camera port and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="cameraPort">The camera port which image data is coming from.</param> /// <param name="cancellationToken">A CancellationToken to observe while waiting for a task to complete.</param> /// <returns>The awaitable Task.</returns> public async Task ProcessAsync(IOutputPort cameraPort, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(); if (handlerComponents.Count == 0) { await this.ProcessRawAsync(cameraPort, cancellationToken); return; } var tasks = new List <Task>(); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.ForceStopProcessing = false; foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.Start(); tasks.Add(port.Trigger.Task); } } component.EnableConnections(); } this.Camera.SetShutterSpeed(MMALCameraConfig.ShutterSpeed); // Prepare arguments for the annotation-refresh task var ctsRefreshAnnotation = new CancellationTokenSource(); var refreshInterval = (int)(MMALCameraConfig.Annotate?.RefreshRate ?? 0); if (!(MMALCameraConfig.Annotate?.ShowDateText ?? false) && !(MMALCameraConfig.Annotate?.ShowTimeText ?? false)) { refreshInterval = 0; } // We now begin capturing on the camera, processing will commence based on the pipeline configured. this.StartCapture(cameraPort); if (cancellationToken == CancellationToken.None) { await Task.WhenAny( Task.WhenAll(tasks), RefreshAnnotations(refreshInterval, ctsRefreshAnnotation.Token)).ConfigureAwait(false); ctsRefreshAnnotation.Cancel(); } else { await Task.WhenAny( Task.WhenAll(tasks), RefreshAnnotations(refreshInterval, ctsRefreshAnnotation.Token), cancellationToken.AsTask()).ConfigureAwait(false); ctsRefreshAnnotation.Cancel(); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks).ConfigureAwait(false); } this.StopCapture(cameraPort); // Cleanup each connected downstream component. foreach (var component in handlerComponents) { foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.DisablePort(); } } component.CleanPortPools(); component.DisableConnections(); } }
/// <summary> /// Helper method to begin processing image data. Starts the Camera port and awaits until processing is complete. /// Cleans up resources upon finish. /// </summary> /// <param name="cameraPort">The camera port which image data is coming from.</param> /// <param name="cancellationToken">A CancellationToken to observe while waiting for a task to complete.</param> /// <returns>The awaitable Task.</returns> public async Task ProcessAsync(IOutputPort cameraPort, CancellationToken cancellationToken = default(CancellationToken)) { var handlerComponents = this.PopulateProcessingList(); if (handlerComponents.Count == 0) { await this.ProcessRawAsync(cameraPort, cancellationToken); return; } var tasks = new List <Task>(); // Enable all connections associated with these components foreach (var component in handlerComponents) { component.EnableConnections(); component.ForceStopProcessing = false; foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.Start(); tasks.Add(port.Trigger.Task); } } } // We now begin capturing on the camera, processing will commence based on the pipeline configured. this.StartCapture(cameraPort); if (cancellationToken == CancellationToken.None) { await Task.WhenAll(tasks).ConfigureAwait(false); } else { await Task.WhenAny(Task.WhenAll(tasks), cancellationToken.AsTask()).ConfigureAwait(false); foreach (var component in handlerComponents) { component.ForceStopProcessing = true; } await Task.WhenAll(tasks).ConfigureAwait(false); } this.StopCapture(cameraPort); // Cleanup each connected downstream component. foreach (var component in handlerComponents) { foreach (var port in component.ProcessingPorts.Values) { if (port.ConnectedReference == null) { port.DisablePort(); } } component.CleanPortPools(); component.DisableConnections(); } }
/// <summary> /// Creates a task the completes when the cancellation token enters /// the cancelled state. /// </summary> public static Task AsTask(this CancellationToken cancellationToken) { return(cancellationToken.AsTask(0)); }
public override async Task <Envelope> ReceiveAsync(CancellationToken cancellationToken) { EnsureOpen("receive"); var segments = new List <BufferSegment>(); await _receiveSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { EnsureOpen("receive"); while (!_receiveCts.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); var segment = new BufferSegment { Buffer = _arrayPool.Rent(_bufferSize) }; segments.Add(segment); // The websocket class go to the 'Aborted' state if the receiveasync operation is cancelled. // In this case, we are unable to close the connection clearly when required. var receiveTask = WebSocket.ReceiveAsync(new ArraySegment <byte>(segment.Buffer), _receiveCts.Token); var cancellationTask = cancellationToken.AsTask(); // If the token is cancelled var completedTask = await Task.WhenAny(receiveTask, cancellationTask).ConfigureAwait(false); if (completedTask != receiveTask) { // The task above will thrown a TaskCancelledException, but just in case... cancellationToken.ThrowIfCancellationRequested(); } var receiveResult = await receiveTask; if (receiveResult == null) { continue; } segment.Count = receiveResult.Count; if (receiveResult.MessageType == WebSocketMessageType.Close) { HandleCloseMessage(receiveResult); break; } if (receiveResult.MessageType != _webSocketMessageType) { CloseStatus = WebSocketCloseStatus.InvalidMessageType; CloseStatusDescription = "An unsupported message type was received"; throw new InvalidOperationException(CloseStatusDescription); } if (receiveResult.EndOfMessage) { break; } if (segments.Count + 1 > DEFAULT_MAX_BUFFER_COUNT) { throw new BufferOverflowException("Maximum buffer size reached"); } } } catch (WebSocketException) { foreach (var segment in segments) { _arrayPool.Return(segment.Buffer); } await CloseWithTimeoutAsync().ConfigureAwait(false); throw; } catch (Exception) { foreach (var segment in segments) { _arrayPool.Return(segment.Buffer); } throw; } finally { _receiveSemaphore.Release(); } string serializedEnvelope = null; // Build the serialized envelope using the buffers using (var stream = new MemoryStream()) { foreach (var segment in segments) { stream.Write(segment.Buffer, 0, segment.Count); _arrayPool.Return(segment.Buffer); } var buffer = stream.ToArray(); serializedEnvelope = Encoding.UTF8.GetString(buffer, 0, buffer.Length); } if (_traceWriter != null && _traceWriter.IsEnabled) { await _traceWriter.TraceAsync(serializedEnvelope, DataOperation.Receive).ConfigureAwait(false); } if (string.IsNullOrWhiteSpace(serializedEnvelope)) { return(null); } return(_envelopeSerializer.Deserialize(serializedEnvelope)); }
/// <summary> /// The task will be awaited until the cancellation token is triggered. (await task unless cancelled). /// </summary> /// <remarks>This is different from cancelling the task. The use case is to enable a calling method /// bow out of the await that it can't cancel, but doesn't require completion/cancellation in order to cancel it's own execution.</remarks> /// <param name="task">The task to await.</param> /// <param name="cancellationToken">The cancellation token to stop awaiting.</param> /// <returns>The task that can be awaited unless the cancellation token is triggered.</returns> public static async Task Unless(this Task task, CancellationToken cancellationToken) { await(await Task.WhenAny(task, cancellationToken.AsTask())); }
protected override async Task RunAsync(CancellationToken cancellationToken) { // not going to actually do anything here - just exit when cancellationToken is signaled await cancellationToken.AsTask(); }
/// <summary> /// Whens all. /// </summary> /// <param name="token">The token.</param> /// <param name="tasks">The tasks.</param> /// <returns></returns> public Task WhenAll(CancellationToken token, params Task[] tasks) { return(Task.WhenAny(Task.WhenAll(tasks), token.AsTask())); }
/// <summary> /// The task will be awaited until the cancellation token is triggered. (await task unless cancelled). /// </summary> /// <remarks>This is different from cancelling the task. The use case is to enable a calling method /// bow out of the await that it can't cancel, but doesn't require completion/cancellation in order to cancel it's own execution.</remarks> /// <param name="task">The task to await.</param> /// <param name="cancellationToken">The cancellation token to stop awaiting.</param> /// <returns>The task that can be awaited unless the cancellation token is triggered.</returns> public async static Task <T> Unless <T>(this Task <T> task, CancellationToken cancellationToken) { return((await Task.WhenAny(task, cancellationToken.AsTask())) is Task <T> result ? result.Result : default(T)); }
/// <summary> /// The task will be awaited until the cancellation token is triggered. (await task unless cancelled). /// </summary> /// <remarks>This is different from cancelling the task. The use case is to enable a calling method /// bow out of the await that it can't cancel, but doesn't require completion/cancellation in order to cancel it's own execution.</remarks> /// <param name="task">The task to await.</param> /// <param name="cancellationToken">The cancellation token to stop awaiting.</param> /// <returns>The task that can be awaited unless the cancellation token is triggered.</returns> public static Task Unless(this Task task, CancellationToken cancellationToken) { return(Task.WhenAny(task, cancellationToken.AsTask())); }