我有两个通过命名管道连接的简单应用程序。在客户端,我有一个方法,每隔n ms检查传入的消息:
private void timer_Elapsed(Object sender, ElapsedEventArgs e)
{
IFormatter f = new BinaryFormatter();
try
{
object temp = f.Deserialize(pipeClient); //hangs here
result = (Func<T>)temp;
}
catch
{
}
}
在开头管道为空,f.Deserialize方法挂起整个应用程序。我甚至无法检查管道是否空了?有没有解决这个问题的方法?
UPD:尝试过XmlSerializer,一切都是一样的。
答案 0 :(得分:0)
你身上的东西是格式化程序在内部进行的pipeClient.Read(
调用。
当您致电Read
时,这是Stream
的预期行为:
返回值
输入:System.Int32
读入缓冲区的总字节数。这可能小于字节数 请求当前可用的字节数,如果是,则为0 到达流的末尾。
因此,如果数据流是支持超时的流类型,则流将阻塞直到数据显示或抛出超时异常。它永远不会在没有读取任何内容的情况下返回,除非您“在流的末尾”,PipeStream
(或类似的NetworkStream
)仅在连接关闭时发生。
解决问题的方法是不要使用计时器来检查新消息是否到达,只需启动后台线程并将其置于循环中,它将自行阻止,直到出现消息。
class YourClass
{
public YourClass(PipeStream pipeClient)
{
_pipeClient = pipeClient;
var task = new Task(MessageHandler, TaskCreationOptions.LongRunning);
task.Start();
}
//SNIP...
private void MessageHandler()
{
while(_pipeClient.IsConnected)
{
IFormatter f = new BinaryFormatter();
try
{
object temp = f.Deserialize(_pipeClient);
result = (Func<T>)temp;
}
catch
{
//You really should do some kind of logging.
}
}
}
}