Exemplo n.º 1
0
 public static Task WaitAsync(this AsyncCountdownEvent countdownEvent, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.WhenAny(countdownEvent.WaitAsync(), cancellationToken.AsTask()));
 }
Exemplo n.º 2
0
        /// <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();
            }
        }
Exemplo n.º 3
0
 public static Task <TResult> AsCancelable <TResult>(this Task <TResult> originalTask, CancellationToken cancellationToken)
 {
     return(Task.WhenAny(originalTask, cancellationToken.AsTask <TResult>()).Unwrap());
 }
Exemplo n.º 4
0
 public static Task WaitAsync(this AsyncManualResetEvent resetEvent, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.WhenAny(resetEvent.WaitAsync(), cancellationToken.AsTask()));
 }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
 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));
 }
Exemplo n.º 7
0
        /// <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();
            }
        }
Exemplo n.º 8
0
        /// <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();
            }
        }
Exemplo n.º 9
0
        /// <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()));
 }
Exemplo n.º 12
0
 protected override async Task RunAsync(CancellationToken cancellationToken)
 {
     // not going to actually do anything here - just exit when cancellationToken is signaled
     await cancellationToken.AsTask();
 }
Exemplo n.º 13
0
 /// <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()));
 }
Exemplo n.º 14
0
 /// <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));
 }
Exemplo n.º 15
0
 /// <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()));
 }