public void Dispose()
 {
     if (!disposed)
     {
         disposed = true;
         stream?.Dispose();
         reader.Dispose();
         writer.Dispose();
     }
 }
        private async Task Run()
        {
            var cancellationToken = this.dispatcherTaskCancellationTokenSource.Token;

            try {
                while (!cancellationToken.IsCancellationRequested)
                {
                    var obj = await reader.ReadAsync(cancellationToken);

                    var             type = obj.GetType();
                    Action <object> handler;
                    if (handlersByType.TryGetValue(type, out handler))
                    {
                        handler(obj);
                    }
                    else
                    {
                        throw new DispatcherUnhandledPortableObjectException(type);
                    }
                }
            } catch (SocketException e) {
                logger.Error("Caught socket exception", e);
                Console.WriteLine(e);
            } catch (DispatcherUnhandledPortableObjectException e) {
                logger.Error("Dispatcher caught unhandled pof exception", e);
                Console.WriteLine(e);
            } catch (OperationCanceledException e) {
                logger.Info("Dispatcher caught operation cancelled exception", e);
                Console.WriteLine(e);
            } catch (Exception e) {
                logger.Error("Dispatcher caught unexpected exception", e);
                Console.WriteLine(e);
            } finally {
                shutdownHandlers.ForEach(x => x.Invoke());
                reader.Dispose();
            }
        }