Beispiel #1
0
        internal async Task <IncomingMessage> PerformRequestAsync(CancellationToken cancellationToken)
        {
            int retryCounter = 0;

            IncomingMessage reply       = null;
            var             reassembler = new MessageReassembler(ctrl, this);

            Debug.WriteLine("timeout is " + waitRetryTimeout.TotalMilliseconds + "ms");

            while (retryCounter++ <= retries)
            {
                // send message
                if (await outgoingMsg.SendAsync().ConfigureAwait(false))
                {
                    // if this request is for a reboot, we won't be able to receive the reply right away because the device is rebooting
                    if ((outgoingMsg.Header.m_cmd == Commands.c_Monitor_Reboot) && retryCounter == 1)
                    {
                        // wait here for
                        Task.Delay(2000).Wait();
                    }

                    CancellationTokenSource source = new CancellationTokenSource();
                    // add a cancellation token to force cancel
                    var timeoutCancelatioToken = source.Token.AddTimeout(waitRetryTimeout);

                    // because we have an external cancellation token and the above timeout cancellation token, need to combine both
                    var linkedCancelationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCancelatioToken).Token;

                    try
                    {
                        // need to have a timeout to cancel the process task otherwise it may end up waiting forever for this to return
                        // because we have an external cancellation token and the above timeout cancellation token, need to combine both
                        reply = await reassembler.ProcessAsync(linkedCancelationToken).ConfigureAwait(false);
                    }
                    catch { }
                    finally
                    {
                        // ALWAYS cancel reassembler task
                        source.Cancel();
                    }

                    if (reply != null)
                    {
                        return(reply);
                    }
                }
                else
                {
                    // send failed
                    Debug.WriteLine("SEND FAILED...");
                }

                // something went wrong, retry with a progressive back-off strategy
                Task.Delay(200 * retryCounter).Wait();
            }

            Debug.WriteLine("exceeded attempts count...");

            return(null);
        }
Beispiel #2
0
        internal async Task <IncomingMessage> PerformRequestAsync(CancellationToken cancellationToken)
        {
            int retryCounter = 0;

            IncomingMessage reply;
            var             reassembler = new MessageReassembler(ctrl, this);


            while (retryCounter++ < retries)
            {
                // send message
                if (await outgoingMsg.SendAsync().ConfigureAwait(false))
                {
                    // need to have a timeout to cancel the process task otherwise it may end up waiting forever for this to return
                    // because we have an external cancellation token and the above timeout cancellation token, need to combine both
                    reply = await reassembler.ProcessAsync(cancellationToken.AddTimeout(waitRetryTimeout)).ConfigureAwait(false);

                    if (reply != null)
                    {
                        return(reply);
                    }
                }
                else
                {
                    // send failed
                    Debug.WriteLine("SEND FAILED...");
                }

                // something went wrong, retry with a progressive back-off strategy
                await Task.Delay(200 *retryCounter);
            }

            Debug.WriteLine("exceeded attempts count...");

            return(null);
        }
Beispiel #3
0
        internal async Task <IncomingMessage> PerformRequestAsync()
        {
            int retryCounter = 0;

            IncomingMessage reply       = null;
            var             reassembler = new MessageReassembler(ctrl, this);

            while (retryCounter++ <= retries)
            {
                //// TODO add cancel token argument here
                //// check for cancelation request
                //if (cancellationToken.IsCancellationRequested)
                //{
                //    // cancellation requested
                //    Debug.WriteLine("cancelation requested");
                //    return null;
                //}

                Debug.WriteLine($"Performing {retryCounter}/{ (retries+1) } request attempt with {waitRetryTimeout.TotalMilliseconds}ms");

                // create new cancelation token source
                CancellationTokenSource cTSource = new CancellationTokenSource();

                // send message
                // add a cancellation token to force cancel, the send
                if (await outgoingMsg.SendAsync(cTSource.Token))
                {
                    // if this request is for a reboot, we won't be able to receive the reply right away because the device is rebooting
                    if (outgoingMsg.Header.Cmd == Commands.c_Monitor_Reboot)
                    {
                        // done here, no reply will come
                        return(reply);
                    }

                    Debug.WriteLine($"Processing reply now...");

                    // create new cancelation token for reply processor
                    cTSource = new CancellationTokenSource();

                    try
                    {
                        // need to have a timeout to cancel the process task otherwise it may end up waiting forever for this to return
                        // because we have an external cancellation token and the above timeout cancellation token, need to combine both
                        reply = await reassembler.ProcessAsync(cTSource.Token.AddTimeout(waitRetryTimeout));
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine($"Exception occurred: {ex.Message}\r\n {ex.StackTrace}");

                        // ALWAYS cancel reassembler task on exception
                        cTSource.Cancel();
                    }

                    if (reply != null)
                    {
                        return(reply);
                    }
                }
                else
                {
                    // send failed
                    Debug.WriteLine("SEND FAILED...");
                }

                // something went wrong, retry with a progressive back-off strategy
                Task.Delay(200 * retryCounter).Wait();
            }

            Debug.WriteLine($"Performing request exceeded attempts count...");

            return(reply);
        }