首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步使用NamedPipeServerStream和NamedPipeClientStream

异步使用NamedPipeServerStream和NamedPipeClientStream
EN

Stack Overflow用户
提问于 2018-01-02 10:36:34
回答 1查看 7.4K关注 0票数 6

对于服务器/客户端架构,我有以下要求:

  1. 编写异步工作的服务器/客户端。
  2. 通信必须是双工的,即在两端进行读写。
  3. 多个客户端可以在任何给定时间连接到服务器。
  4. 服务器/客户端应该等待,直到它们可用,并最终建立连接。
  5. 一旦客户端连接,它就应该写入流。
  6. 然后服务器应该从流中读取并将响应写回客户端。
  7. 最后,客户端应该读取响应,通信应该结束。

因此,考虑到以下要求,我编写了以下代码,但我不太确定,因为管道的文档有点缺乏,不幸的是,代码似乎不能正常工作,它挂在某个点上。

代码语言:javascript
运行
复制
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,最后,它应该打印“完成!”。

备注:

  1. 我在.NET框架4.7.1和.NET Core2.0上测试了它,并得到了相同的结果。
  2. 客户端和服务器之间的总是本地的,其中客户端是web应用程序,可以排队执行一些任务,比如启动第三方进程,并且服务器将部署为与部署这些客户端的web服务器相同的机器上的服务。
EN

回答 1

Stack Overflow用户

发布于 2018-01-03 01:24:44

当断开连接时,WaitForPipeDrain()可能会因为管道断裂而抛出IOException

如果这发生在您的服务器Task中,那么它将永远不会侦听下一个连接,所有剩余的客户端连接都挂在ConnectAsync()上。

如果在其中一个客户端任务中发生这种情况,则不会继续恢复和增加该索引的计数器。

如果将对WaitForPipeDrain()的调用包装在try/catch中,程序将永远继续运行,因为函数HandleRequestAsync()是无限递归的。

简而言之,要想让它发挥作用:

  1. 处理来自IOExceptionWaitForPipeDrain()
  2. HandleRequestAsync()必须在某个时候完成。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48059410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档