命名管道 - 异步查看
我需要找到一种方法,当以异步模式打开的 System.IO.Pipe.NamedPipeServerStream 有更多可供读取的数据时收到通知 - WaitHandle 是理想的选择。我不能简单地使用 BeginRead() 来获取这样的句柄,因为我可能会收到另一个想要写入管道的线程的信号 - 所以我必须释放管道上的锁并等待写入完成,并且 NamedPipeServerStream 没有 CancelAsync 方法。我还尝试调用 BeginRead(),然后在线程收到信号时在管道上调用 win32 函数 CancelIO,但我认为这不是一个理想的解决方案,因为如果在数据到达并正在处理时调用 CancelIO,它将被删除-我仍然希望保留这些数据,但在写入后稍后处理它。我怀疑 win32 函数 PeekNamedPipe 可能有用,但我想避免必须用它不断轮询新数据。
如果上面的文字有点不清楚,这大概是我想要做的......
NamedPipeServerStream pipe;
ManualResetEvent WriteFlag;
//initialise pipe
lock (pipe)
{
//I wish this method existed
WaitHandle NewDataHandle = pipe.GetDataAvailableWaithandle();
Waithandle[] BreakConditions = new Waithandle[2];
BreakConditions[0] = NewDataHandle;
BreakConditions[1] = WriteFlag;
int breakcode = WaitHandle.WaitAny(BreakConditions);
switch (breakcode)
{
case 0:
//do a read on the pipe
break;
case 1:
//break so that we release the lock on the pipe
break;
}
}
I need to find a way to be notified when a System.IO.Pipe.NamedPipeServerStream opened in asynchronous mode has more data available for reading on it- a WaitHandle would be ideal. I cannot simply use BeginRead() to obtain such a handle because it's possible that i might be signaled by another thread which wants to write to the pipe- so I have to release the lock on the pipe and wait for the write to be complete, and NamedPipeServerStream doesnt have a CancelAsync method. I also tried calling BeginRead(), then calling the win32 function CancelIO on the pipe if the thread gets signaled, but I don't think this is an ideal solution because if CancelIO is called just as data is arriving and being processed, it will be dropped- I still wish to keep this data, but process it at a later time, after the write. I suspect the win32 function PeekNamedPipe might be useful but i'd like to avoid having to continuously poll for new data with it.
In the likley event that the above text is a bit unclear, here's roughly what i'd like to be able to do...
NamedPipeServerStream pipe;
ManualResetEvent WriteFlag;
//initialise pipe
lock (pipe)
{
//I wish this method existed
WaitHandle NewDataHandle = pipe.GetDataAvailableWaithandle();
Waithandle[] BreakConditions = new Waithandle[2];
BreakConditions[0] = NewDataHandle;
BreakConditions[1] = WriteFlag;
int breakcode = WaitHandle.WaitAny(BreakConditions);
switch (breakcode)
{
case 0:
//do a read on the pipe
break;
case 1:
//break so that we release the lock on the pipe
break;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,所以我只是将其从代码中删除,希望删除了所有应用程序逻辑内容。这个想法是,您尝试使用 ReadFile 进行零长度读取,并等待 lpOverlapped.EventHandle(读取完成时触发)和当另一个线程想要写入管道时设置的 WaitHandle。如果由于写入线程而导致读取中断,请使用 CancelIoEx 取消零长度读取。
Ok, so I just ripped this out of my code, hopefully I deleted all the application logic stuff. The idea is that you try a zero-length read with ReadFile and wait on both the lpOverlapped.EventHandle (fired when the read completes) and a WaitHandle set when another thread wants to write to the pipe. If the read is to be interrupted due to a writing thread, use CancelIoEx to cancel the zero-length read.
浏览 MSDN,我没有看到任何机制可以做你想做的事情。最快的解决方案可能是使用互操作来访问 PeekNamedPipe。如果您不想使用互操作,可以在自定义类中抽象管道,并在抽象中提供查看功能。抽象将处理所有信号并且必须协调对管道的读取和写入。显然,这不是一项微不足道的任务。
如果您的情况可能的话,另一种选择是考虑使用 WCF,这几乎就是一种抽象。
Looking through MSDN, I don't see any mechanism to do what you want. The quickest solution is porbably to use interop to access
PeekNamedPipe
. If you don't want to useinterop
, you can abstract the pipe inside a custom class and provide the peek functionality within the abstraction. The abstraction would handle all the signaling and have to coordinate reading and writing to the pipe. Obviously, not a trivial task.Another alternative, if possible in your situation, is to look into using WCF which is pretty much that abstraction.