gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:13 25 4
gpt4 key购买 nike

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

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

我的代码的最小化版本如下 (.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.

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

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

    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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com