c# - 如何从强制终止管道中正确清除异步回调?

标签 c# asynchronous .net-3.5 named-pipes

我正在尝试创建一个防御性命名管道服务器,其他应用程序可以读取简单的状态值。我只对单个命名管道实例感兴趣,客户端可以在其中连接、读取状态并断开连接。

我遇到的问题是试图保护我的管道免遭不当使用;特别是防止单个进程获得控制权并且永远不会放开我的命名管道。我试图在超时后强制断开/关闭管道以终止连接;该尝试允许我的服务器继续,但是,当我结束连接时,不会调用异步回调。

我的代码的最小化版本如下(.NET 3.5)...

服务器端]

  static AutoResetEvent autoEvent = new AutoResetEvent(false);

  static void Main(string[] args)
  {
      NamedPipeServerStream pipe = new NamedPipeServerStream("TestSimplePipe", PipeDirection.Out);

      Console.WriteLine("Waiting for client...");
      pipe.WaitForConnection();

      Console.WriteLine("About to BeginWrite...");
      pipe.BeginWrite(new byte[1] { 0x00 }, 0, 1, new AsyncCallback(ProcessWrite), pipe);

      Console.WriteLine("Waiting...");
      bool hasSignal = autoEvent.WaitOne(5000);
      if (hasSignal == false)
      {
          Console.WriteLine("Client took to long.");
      }

      Console.WriteLine("Closing pipe.");
      pipe.Close();
      Console.ReadLine();
  }

  static void ProcessWrite(IAsyncResult result)
  {
      try
      {
          Console.WriteLine("Ending write...");
          NamedPipeServerStream pipe = result.AsyncState as NamedPipeServerStream;
          pipe.EndWrite(result);

          Console.WriteLine("Wrote successfully!");
      }
      catch (Exception)
      {
          Console.WriteLine("Write not completed.");
      }

      autoEvent.Set();
  }

客户端]

  static void Main(string[] args)
  {
      using (NamedPipeClientStream npcs = new NamedPipeClientStream(".", "TestSimplePipe", PipeDirection.In))
      {
          Console.WriteLine("Connecting to server...");
          npcs.Connect();
          Console.WriteLine("Connected!");

          //Thread.Sleep(15000);

          Console.WriteLine("Reading byte...");
          npcs.ReadByte();
          Console.WriteLine("Byte read!");
      }

      Console.WriteLine("Done!");
      Console.ReadLine();
  }

如果一切都按计划设计,我会得到以下输出:

服务器端]

    Waiting for client...
    About to BeginWrite...
    Waiting...
    Ending write...
    Wrote successfully!
    Closing pipe.

客户端]

    Connecting to server...
    Connected!
    Reading byte...
    Byte read!
    Done!

但是,如果我在客户端代码中启用 sleep ,服务器将不会从回调中输出任何内容:

    Waiting for client...
    About to BeginWrite...
    Waiting...
    Client took to long.
    Closing pipe.

我假设在关闭时,将调用回调并抛出“ObjectDisposeException”。相反,当我关闭服务器管道时,不会调用回调。

还让我害怕的是,如果我等待客户端 sleep 的整个持续时间而不结束服务器管道应用程序,则将在服务器上调用回调,并且我将收到服务器的以下输出:

    Waiting for client...
    About to BeginWrite...
    Waiting...
    Client took to long.
    Closing pipe.
    Ending write...
    Write not completed.

我并不担心清理异步调用,但担心它由于第三方应用程序而以某种方式保持事件状态。当我终止回调所附加的管道时,如何正确清理异步回调?

最佳答案

您可以多次打开同一个命名管道。您应该同时接受多个客户。这样,没有任何客户端可以阻止端点。 This is shown in a native code example on MSDN.您可以将该代码移植到 .NET。也许,您应该使用异步 IO,这样您就不会用完许多客户端的线程。

另一方面,恶意客户端可能会导致资源耗尽,或者通过向服务器发送垃圾邮件连接而导致其他客户端无法连接。我不知道有什么方法可以防止这种情况。

关于c# - 如何从强制终止管道中正确清除异步回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18644631/

相关文章:

c# - 删除 Amazon S3 存储桶中早于 X 天的每个文件的版本

c# - 以编程方式访问谷歌浏览器历史记录

c# - 给定 IP 地址和网络掩码后,如何计算 IP 范围?

c# - Azure Functions - 当我尝试本地调试时,配置设置返回 null

c++ - 在一个线程中完成的操作对另一个线程可见,而无需显式同步

java - 如何持续观察对象直到 onError()/取消订阅

c# - 扩展方法是如何编译的?

vb.net - 如何在 RichTextBox 中隐藏插入符号?

c# - 如何获得枚举标志值的最短表示?

java - 如何设置java.util.concurrent.Future的结果?