Ejemplo n.º 1
0
        /// <summary>
        /// Starts the link control reader; should be called by link implementation after the link is connected.
        /// </summary>
        /// <param name="ctrlReader">CtrlReader instance used to read from the link.</param>
        /// <returns>A task that can be awaited on.</returns>
        protected async Task StartLinkAsync(CtrlReader ctrlReader)
        {
            // Check to make sure the link has been cleaned up, if it was used previously
            if (this.readCancellationSource != null)
            {
                throw new InvalidOperationException("Invalid state; CleanupLink() did not run before link re-use");
            }

            this.readCancellationSource = new CancellationTokenSource();

            // ConfigureAwait so that it will not run on same thread
            await this.CreateReadingTask(ctrlReader, this.readCancellationSource.Token).ConfigureAwait(false);

            this.IsConnected = true;
            this.OnCtrlLinkConnected();
            await this.SendActiveSubscriptions();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a reading task.
        /// </summary>
        /// <param name="ctrlReader">CtrlReader instance used to read from the link.</param>
        /// <param name="cts">Cancellation token for the read class.</param>
        /// <returns>Task that can be awaited on.</returns>
        private Task CreateReadingTask(CtrlReader ctrlReader, CancellationToken cts)
        {
            return(Task.Factory.StartNew(
                       async() =>
            {
                try
                {
                    Message msg = null;

                    // We need to read at least one byte:
                    uint readBytes = 1;

                    while (!cts.IsCancellationRequested)
                    {
                        if (msg == null)
                        {
                            msg = new Message();
                        }

                        uint byteCount = await ctrlReader.LoadAsync(readBytes);

                        // Unless we figure out below how many bytes we need, let's set it to the default,
                        // safe value of one byte. It may have been changed to something bigger
                        // if we were reading the rest of a larger message.
                        readBytes = 1;

#if DEBUG2
                        Debug.WriteLine("Read " + byteCount + " bytes");
#endif

                        if (byteCount == 0)
                        {
                            Debug.WriteLine("Control link closed in reader.");
                            this.LinkClosed();
                            return;
                        }

                        int reqBytes = 0;

                        try
                        {
                            reqBytes = msg.DeserializeBaseMessage(ctrlReader);
                        }
                        catch (Protocol.ProtoException e)
                        {
                            Debug.WriteLine("Protocol exception while deserializing base message: " + e);
                            this.OnCtrlLinkError(e);
                            this.LinkClosed();
                            return;
                        }

                        if (reqBytes < 1)
                        {
#if DEBUG2
                            Debug.WriteLine("Received complete message - delivering");
#endif

                            CtrlMessageReceived(msg);
                            msg = null;
                        }
                        else
                        {
#if DEBUG2
                            Debug.WriteLine("DeserializeBase needs " + reqBytes + " bytes more.");
#endif
                            // Now we know exactly how many bytes we need.
                            // We may need more than that, but this is the "at least this many bytes" value,
                            // so it is safe to read this much. If it is not enough,
                            // we will have a better idea the next time we read something.
                            readBytes = ( uint )reqBytes;
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Unknown exception inside read loop: " + e);
                    this.OnCtrlLinkError(e);
                    this.LinkClosed();
                    return;
                }
            },
                       cts));
        }