对于服务器/客户端架构,我有以下要求:
因此,考虑到以下要求,我编写了以下代码,但我不太确定,因为管道的文档有点缺乏,不幸的是,代码似乎不能正常工作,它挂在某个点上。
namespace PipesAsyncAwait471
{
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Threading.Tasks;
internal class Program
{
private static async Task Main()
{
List<Task> tasks = new List<Task> {
HandleRequestAsync(),
};
tasks.AddRange(Enumerable.Range(0, 10).Select(i => SendRequestAsync(i, 0, 5)));
await Task.WhenAll(tasks);
}
private static async Task HandleRequestAsync()
{
using (NamedPipeServerStream server = new NamedPipeServerStream("MyPipe",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous))
{
Console.WriteLine("Waiting...");
await server.WaitForConnectionAsync().ConfigureAwait(false);
if (server.IsConnected)
{
Console.WriteLine("Connected");
if (server.CanRead) {
// Read something...
}
if (server.CanWrite) {
// Write something...
await server.FlushAsync().ConfigureAwait(false);
server.WaitForPipeDrain();
}
server.Disconnect();
await HandleRequestAsync().ConfigureAwait(false);
}
}
}
private static async Task SendRequestAsync(int index, int counter, int max)
{
using (NamedPipeClientStream client = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut, PipeOptions.Asynchronous))
{
await client.ConnectAsync().ConfigureAwait(false);
if (client.IsConnected)
{
Console.WriteLine($"Index: {index} Counter: {counter}");
if (client.CanWrite) {
// Write something...
await client.FlushAsync().ConfigureAwait(false);
client.WaitForPipeDrain();
}
if (client.CanRead) {
// Read something...
}
}
if (counter <= max) {
await SendRequestAsync(index, ++counter, max).ConfigureAwait(false);
}
else {
Console.WriteLine($"{index} Done!");
}
}
}
}
}
Assumptions:
我期望它工作的方式是,当我调用SendRequestAsync
并发执行时,我所做的所有请求,然后每个请求都会发出额外的请求,直到到达6
,最后,它应该打印“完成!”。
备注:
发布于 2018-01-03 01:24:44
当断开连接时,WaitForPipeDrain()
可能会因为管道断裂而抛出IOException
。
如果这发生在您的服务器Task
中,那么它将永远不会侦听下一个连接,所有剩余的客户端连接都挂在ConnectAsync()
上。
如果在其中一个客户端任务中发生这种情况,则不会继续恢复和增加该索引的计数器。
如果将对WaitForPipeDrain()
的调用包装在try
/catch
中,程序将永远继续运行,因为函数HandleRequestAsync()
是无限递归的。
简而言之,要想让它发挥作用:
IOException
的WaitForPipeDrain()
HandleRequestAsync()
必须在某个时候完成。https://stackoverflow.com/questions/48059410
复制相似问题