堅牢なタイムアウト管理を使用して名前付きパイプIPCを実装する最善の方法を見つけるのに苦労しています。私は、接続の確立時にタイムアウトを意味するのではなく、読み書きストリームでタイムアウトを意味します。名前付きパイプの例読み取り/書き込みタイムアウトを使用するIPC
私が見つけたすべての例には、タイムアウトの実装がありません。
誰かが私に実例を教えてくれますか、これを示す例を教えてください。
堅牢なタイムアウト管理を使用して名前付きパイプIPCを実装する最善の方法を見つけるのに苦労しています。私は、接続の確立時にタイムアウトを意味するのではなく、読み書きストリームでタイムアウトを意味します。名前付きパイプの例読み取り/書き込みタイムアウトを使用するIPC
私が見つけたすべての例には、タイムアウトの実装がありません。
誰かが私に実例を教えてくれますか、これを示す例を教えてください。
NamedPipeClientStream.BeginRead
と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;
}
}
素晴らしい例。私はこれを試してみる。 –
名前付きパイプを使用しようとしていますか、名前付きパイプでWCFを使用していますか? –
@AdamGritt:名前付きパイプ。 –