【发布时间】:2017-05-02 15:30:39
【问题描述】:
我正在尝试编写一个控制台应用程序
- 从 TcpClient 接收打开的 Stream
- 从控制台获取输入并将其写入此 Stream
- 接收响应并将其写入 控制台。
我尝试对这些操作使用 async/await,但不断收到异常。 这是我的代码:
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);
}
}
这里是个例外
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
我怀疑我刚刚锁定了流,或者那里的异步方法使用存在其他问题。
所以我尝试创建不同的线程,但它们根本不起作用
Task.Run(() =>{
while(true)
{
WriteAsync(stream);
}
});
Task.Run(() =>{
while(true)
{
ReadAsync(stream);
}
});
我在异步和多线程方面都没有什么经验,所以你可以指出我,问题出在哪里?
【问题讨论】:
-
我注意到
ReadAsync方法将控制台的标准输出流作为sourceStream传递给尝试从中读取数据的CopyStream方法。因此,您正在尝试从输出流中读取数据。 -
@LucaCremonesi 你是对的,我已经解决了这个问题,但事实并非如此,因为应用程序似乎在“WriteAsync(stream)”调用时崩溃并且永远不会达到“ReadAsync”
标签: c# multithreading asynchronous stream