C# 所有的管道实例都忙。

8
以下代码创建一个新线程,首先作为命名管道客户端发送参数,然后作为服务器检索结果。之后,它在另一个AppDomain中执行一个函数,作为命名管道服务器,然后作为客户端发送结果回来。
public OrderPrice DoAction()
{
  Task<OrderPrice> t = Task<OrderPrice>.Factory.StartNew(NamedPipeClient, parameters);

  if (domain == null)
  {
    domain = AppDomain.CreateDomain(DOMAINNAME);
  }
  domain.DoCallBack(AppDomainCallback);

  return t.Result;
}

static OrderPrice NamedPipeClient(object parameters) {
  OrderPrice price = null;

  using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_TO)) {
    stream.Connect();
    SerializeToStream(stream, parameters);
  }

  using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_BACK)) {
    stream.WaitForConnection();

    price = (OrderPrice)DeserializeFromStream(stream);
  }

  return price;
}

void AppDomainCallback() {
  OrderPrice price = null;

  using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_TO)) {
    stream.WaitForConnection();

    List<object> parameters = (List<object>)DeserializeFromStream(stream);

    if (mi != null)
      price = (OrderPrice)mi.Invoke(action, parameters.ToArray());
}

  using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_BACK)) {
    stream.Connect();
    SerializeToStream(stream, price);
  }
}

平均每秒钟调用一次代码,已经运行了7个小时,一切正常。但是在某个时候,“system.io.ioexception all pipe instances are busy”发生并且它们无法再连接。在这里浏览似乎是因为没有正确处理管道对象的释放,但我认为这些都很好,因为它们在using语句中。有人知道问题出在哪里吗?该代码运行在.NET 4.0上,Windows Server 2008。


4
当您尝试同时从多个线程访问管道时,会抛出异常。管道不是线程安全的,请确认您不会在两个线程之间同时访问它们。 - hcb
当创建多个调用DoAction的线程时,代码会在第一次调用时崩溃,因为第二个NamedPipeServerStream(PIPE_TO)实例被创建了。我尝试添加lock(SyncToObject),但代码仍然被输入两次。我认为这是因为它在单独的AppDomain中运行,但我不确定如何在单独的AppDomain中使用对象。 - Serve Laurijssen
你能把对AppDomainCallback()的调用放到任务中吗?或者因为它在另一个域中,这个方法会自动在另一个线程上被调用吗? - hcb
1
确实是一个线程问题,谢谢。通过在DoAction的最高级别添加lock(sync)来解决它。为四个管道对象使用四个同步对象也可以工作,但有时会使代码停滞。 - Serve Laurijssen
2个回答

2

1
另一种可能出现错误信息“System.IO.IOException: 所有管道实例都忙” 的情况是:
当启动一个NamedPipeServerStream时,如果管道名称已被另一个服务器使用,它会抛出此错误。我不能百分之百确定它只在达到最大实例数时抛出,但可能是这种情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接