名前付きパイプを介して相互に通信する2つの.NETアプリケーションがあります。最初はすべてが素晴らしいですが、最初のメッセージが送信され、サーバーが再びリッスンしようとすると、WaitForConnection()
メソッドはメッセージ付きのSystem.IO.Exception
をスローしますパイプが壊れています。
なぜここでこの例外が発生するのですか?パイプを扱うのはこれが初めてですが、過去にも同様のパターンがソケットで機能しました。
コードアホイ!
サーバ:
using System.IO.Pipes;
static void main()
{
var pipe = new NamedPipeServerStream("pipename", PipeDirection.In);
while (true)
{
pipe.Listen();
string str = new StreamReader(pipe).ReadToEnd();
Console.Write("{0}", str);
}
}
クライアント:
public void sendDownPipe(string str)
{
using (var pipe = new NamedPipeClientStream(".", "pipename", PipeDirection.Out))
{
using (var stream = new StreamWriter(pipe))
{
stream.Write(str);
}
}
}
SendDownPipeを最初に呼び出すと、サーバーは私が送信したメッセージを正常に出力しますが、ループバックして再度リッスンすると、うんざりします。
うまくいくように見えるコードを投稿します-パイプで何もしなかったので興味がありました。関連する名前空間でサーバー側の名前を付けたクラスが見つからなかったため、NamedPipeServerStreamに基づくコードを次に示します。コールバックは、2つのプロジェクトに煩わされることができなかったからです。
NamedPipeServerStream s = new NamedPipeServerStream("p", PipeDirection.In);
Action<NamedPipeServerStream> a = callBack;
a.BeginInvoke(s, ar => { }, null);
...
private void callBack(NamedPipeServerStream pipe)
{
while (true)
{
pipe.WaitForConnection();
StreamReader sr = new StreamReader(pipe);
Console.WriteLine(sr.ReadToEnd());
pipe.Disconnect();
}
}
そして、クライアントはこれを行います:
using (var pipe = new NamedPipeClientStream(".", "p", PipeDirection.Out))
using (var stream = new StreamWriter(pipe))
{
pipe.Connect();
stream.Write("Hello");
}
サーバーが稼働している状態で、上記のブロックを複数回繰り返すことができます。問題はありません。
クライアントが切断された後、サーバーからpipe.WaitForConnection()を呼び出すと、問題が発生しました。解決策は、IOExceptionをキャッチしてpipe.Disconnect()を呼び出してから、pipe.WaitForConnection()を再度呼び出すことです。
while (true)
{
try
{
_pipeServer.WaitForConnection();
break;
}
catch (IOException)
{
_pipeServer.Disconnect();
continue;
}
}
同じ問題が発生しました。これは、サーバーのStreamReaderを使用して... End Usingを破棄し、NamedPipeServerStreamも停止することが原因です。解決策は、単に使用しないことです...使用を終了し、ガベージコレクターを信頼します。