我有一个启动
DispatcherTimer
的方法,它从System.IO.Pipes.NamedPipe
读取所有消息。在计时器开始之前,我想阅读第一条消息。
// Initiate the PipeClient
pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.In);
pipeClient.Connect();
//declare executionSymbol
var reader = new StreamReader(pipeClient);
string executionSymbol = reader.ReadLine();
//start reading the messages
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += async (sender, e) => {
// Empty the Pipe...
};
timer.Start();
到目前为止效果很好,但只是因为我很好奇我做了这个改变。
//declare executionSymbol
using (var reader = new StreamReader(pipeClient)) {
string executionSymbol = reader.ReadLine();
}
我没想到它会有任何实际变化,但事实证明,一旦调用该方法,它就会让我的程序崩溃。为什么会这样?随时向我询问更多信息!
在
using
块的末尾,您的 StreamReader 被释放。 处理 StreamReader 会产生关闭底层流的副作用.
下次您访问
pipeClient
(您的基础流)时,您将访问已处置的流,因此会出现异常。您还没有向我们展示您的完整代码,但我有一种预感,这就是 timer.Tick
. 中发生的事情
要解决此问题,您有以下选择:
使用 StreamReader 构造函数之一,允许您保持底层流打开,或者
保留 StreamReader,将其用于所有后续读取,仅在不再需要管道时才处理它。
哦,还有一些让您的软件开发生活更轻松的一般提示:
向您的应用程序添加一个全局的、顶级的异常处理程序。这样,它不会崩溃,但会报告异常详细信息(以某种对您有用的方式)并正常关闭。
下次您在 StackOverflow 上提问时,将异常的确切文本直接添加到您的问题中。这样,人们就不必 guess 是什么让你的程序崩溃了,而是可以检查异常消息和堆栈跟踪。