/** * This will block the executing thread until inputStream is closed */ public void Start(Stream inputStream, TextWriter writer) { var channelClosedCancelationTokenSource = new CancellationTokenSource(); try { if (IsLoggingEnabled) { InitialiseLogger(); } _channel.Init(inputStream, writer); _messageDispatcher.Init(_dispatchMessagesBufferBlock, _channel); _requestExecutor.Init(_requestHandlers, _dispatchMessagesBufferBlock); _responseHandlerExecutor.Init(_responseHandlers, _dispatchMessagesBufferBlock); var messageDispatcherTask = _messageDispatcher.StartAsync(channelClosedCancelationTokenSource.Token); Task.Run(() => { while (_channel.IsOpen) { var channelReadResult = _channel.Read(); foreach (var request in channelReadResult.Requests) { _requestExecutor.ExecuteAsync(request, channelClosedCancelationTokenSource.Token); } foreach (var response in channelReadResult.Responses) { _responseHandlerExecutor.ExecuteAsync(response, channelClosedCancelationTokenSource.Token); } } channelClosedCancelationTokenSource.Cancel(); }); messageDispatcherTask.Wait(); //if anything goes wrong this is where the exceptions come from } catch (AggregateException ex) { Console.Error.WriteLine(ex.Message); if (IsLoggingEnabled) { var flattenedAggregateException = ex.Flatten(); foreach (var exception in flattenedAggregateException.InnerExceptions) { Log.Error(exception, string.Empty); } } else { throw; } } }