简体   繁体   中英

C# Read/write stream async from console application

I am trying to write a console application which

  1. Receives an opened Stream from TcpClient
  2. Gets input from console and writes it to this Stream
  3. Receives the response and writes it to console.

I tried to use async/await for those operations, but keep getting an exception. Here is my code:

   public void Main()
   {
         while(true)
        {
            WriteAsync(stream);

            ReadAsync(stream);
        }
    }

    private static void ReadAsync(Stream stream)
    {
        using (Stream console = Console.OpenStandardOutput())
         {
           CopyStream(stream, console);
         }


    }

    private static void WriteAsync(Stream stream)
    {
         using (Stream console = Console.OpenStandardInput())
         {
             CopyStream(console, stream);
         }

    }

    private static async void CopyStream(Stream sourceStream, Stream targetStream)
    {
             var buffer = new Byte[256];
             int bytesRead = 0;

             while((bytesRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
             {
                 await targetStream.WriteAsync(buffer, 0, bytesRead);
             }

    }

And here is the exception

Unhandled Exception: System.NotSupportedException: Stream does not support reading.
   at System.IO.__Error.ReadNotSupported()
   at System.IO.Stream.BeginReadInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, Boolean serializeAsynchronously, Boolean apm)
   at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at TestBackend.Program.<CopyStream>d__3.MoveNext() in /home/slavskaya/avl_demonstrator/AVL_SCU/Tests/System/Backend/TestBackend/Program.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.QueueUserWorkItemCallbackDefaultContext.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()System.NotSupportedException: Stream does not support reading.
   at System.IO.__Error.ReadNotSupported()
   at System.IO.Stream.BeginReadInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, Boolean serializeAsynchronously, Boolean apm)
   at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at TestBackend.Program.<CopyStream>d__3.MoveNext() in /home/slavskaya/avl_demonstrator/AVL_SCU/Tests/System/Backend/TestBackend/Program.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.QueueUserWorkItemCallbackDefaultContext.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()System.NotSupportedException: Stream does not support reading.
   at System.IO.__Error.ReadNotSupported()
   at System.IO.Stream.BeginReadInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, Boolean serializeAsynchronously, Boolean apm)
   at System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   at TestBackend.Program.<CopyStream>d__3.MoveNext() in /home/slavskaya/avl_demonstrator/AVL_SCU/Tests/System/Backend/TestBackend/Program.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.QueueUserWorkItemCallbackDefaultContext.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
Aborted

I suspect that I just locked the stream, or there is some other problem with async methods usage there.

So I tried creating different threads, but they not working at all

Task.Run(() =>{
          while(true)
    {
       WriteAsync(stream);
    }
        });
  Task.Run(() =>{
          while(true)
    {
         ReadAsync(stream);
    }
        });

I have little experience both with async and multithreading, so you could point me, where is the problem here?

You aren't awaiting each operation, so they will be overlapping too much; you probably want:

public async Task SomeAsyncMethod()
{
     while(true)
    {
        await WriteAsync(stream);

        await ReadAsync(stream);
    }
}

private static async Task ReadAsync(Stream stream)
{
    using (Stream console = Console.OpenStandardOutput())
     {
       await CopyStream(stream, console);
     }


}

private static async Task WriteAsync(Stream stream)
{
     using (Stream console = Console.OpenStandardInput())
     {
         await CopyStream(console, stream);
     }
}

However, calling that from a non-async Main is vexing; it is not a good idea to just Wait()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM