我正在努力寻找实现具有强大超时管理的命名管道IPC的最佳方法.我并不是指建立连接时超时,而是读/写流超时.
我发现的所有示例都没有超时实现.
有人可以给我一个工作实例和/或指向一个显示这个的例子吗?
NamedPipeClientStream.BeginRead您可能需要做的是使用and进行异步读写NamedPipeClientStream.BeginWrite;然后将使用计时器来检测何时一段时间内没有发送或接收数据。
每当发送或接收数据时,DateTime都会将一个字段设置为DateTime.Now,并且每次执行计时器都会检查该字段以确定是否发生超时。如果发生这种情况,NamedPipeClientStream可以关闭 ,并且可以捕获NamedPipeClientStream.EndRead和中的异常。NamedPipeClientStream.EndWrite
我还没有准备好一个工作示例,但如果您需要的话,我会开始编写一个。希望这能同时帮助您。
这是一些非常粗糙的示例代码。还需要做更多的事情,例如实现IDisposable和添加写入方法。不过,这应该有助于说明这个想法。最好使用此代码作为模型,而不是直接使用它。我已经测试了代码,看看它是否可读。
//this is a very rough model of how to do it. a lot more would need to be implemented
//i'm assuming you plan to continuously read from it. i can think up another example if you're not
//also not thread safe
public class MyPipeClient
{
NamedPipeClientStream PipeClient = new NamedPipeClientStream("testpipe1");
Timer TimeoutTimer;
DateTime LastRead;
const int TimeoutSeconds = 120; //2 mins
//will connect and start receiving
public void Connect()
{
PipeClient.Connect();
LastRead = DateTime.Now;
TimeoutTimer = new Timer(TimeoutCheck, this, 0, 1000); //check every second
Read(this);
}
public void Disconnect()
{
PipeClient.Close(); PipeClient = null;
TimeoutTimer.Dispose(); TimeoutTimer = null;
}
static void Read(MyPipeClient client)
{
PipeState state = new PipeState(client);
try
{
client.PipeClient.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state);
}
catch (InvalidOperationException) //disconnected/disposed
{
return;
}
}
static void ReadCallback(IAsyncResult ar)
{
PipeState state = (PipeState)ar.AsyncState;
MyPipeClient client = state.Client;
client.LastRead = DateTime.Now;
int bytesRead;
try
{
bytesRead = client.PipeClient.EndRead(ar);
}
catch (IOException) //closed
{
return;
}
if (bytesRead > 0)
{
byte[] data = state.Buffer;
//TODO: something
}
else //i've never used pipes, so i'm assuming this behavior exists with them
{
client.Disconnect();
return;
}
Read(client);
}
static void TimeoutCheck(object state)
{
MyPipeClient client = (MyPipeClient)state;
TimeSpan timeSinceLastRead = DateTime.Now - client.LastRead;
if (timeSinceLastRead.TotalSeconds > TimeoutSeconds)
{
client.Disconnect();
}
}
}
class PipeState
{
public byte[] Buffer = new byte[4096];
public MyPipeClient Client;
public PipeState(MyPipeClient client)
{
Client = client;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7839 次 |
| 最近记录: |