示例#1
0
        /// <summary>
        /// Reading the incoming messages from the network client and schedules them
        /// with the incoming message queue.
        /// </summary>
        /// <returns>A future which will complete when the client disconnects.</returns>
        private async Task EnqueueIncomingMessages()
        {
            //We need a token for canceling this task when a user disconnects
            CancellationToken incomingCancellationToken = CreateNewManagedCancellationTokenSource().Token;

            try
            {
                while (!incomingCancellationToken.IsCancellationRequested)
                {
                    NetworkIncomingMessage <TPayloadReadType> message = await UnmanagedClient.ReadAsync(incomingCancellationToken)
                                                                        .ConfigureAwait(false);

                    //If the message is null then the connection is no longer valid
                    //The socket likely disconnected so we should stop the network thread
                    if (message == null)
                    {
                        //We have to publish a null so it can be consumed by the user
                        //to know that the socket is dead
                        await IncomingMessageQueue.EnqueueAsync(null, CancellationToken.None)
                        .ConfigureAwait(false);

                        StopNetwork();
                    }


                    //if have to check the token again because the message may be null and may have been canceled mid-read
                    if (incomingCancellationToken.IsCancellationRequested)
                    {
                        continue;
                    }

                    //Try to notify interceptors of a payload that has come in. They may want it
                    if (!InterceptorManager.TryNotifyOutstandingInterceptors(message.Payload))
                    {
                        await IncomingMessageQueue.EnqueueAsync(message, incomingCancellationToken)
                        .ConfigureAwait(false);
                    }
                }
            }
            catch (TaskCanceledException e)
            {
                //This is an expected exception that happens when the token is canceled
                if (Logger.IsDebugEnabled)
                {
                    Logger.Debug($"Expected Task Canceled Exception: {e.Message}\n\n Stack: {e.StackTrace}");
                }

                //We cannot rethrow because this can cause application instability on threadpools
            }
            catch (Exception e)
            {
                if (Logger.IsErrorEnabled)
                {
                    Logger.Error($"Error: {e.Message}\n\n Stack: {e.StackTrace}");
                }

                //We cannot rethrow because this can cause application instability on threadpools
            }
            finally
            {
                try
                {
                    await DisconnectAsync(0);
                }
                catch (Exception)
                {
                }
            }

            //TODO: Should we do anything after the dispatch has stopped?
        }