C#所有管道实例都忙

Posted

技术标签:

【中文标题】C#所有管道实例都忙【英文标题】:C# all pipe instances are busy 【发布时间】:2013-08-26 06:35:39 【问题描述】:

以下代码创建一个新线程,首先作为命名管道客户端发送参数,然后作为服务器检索结果。之后,它在另一个 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 所有管道实例都很忙”被抛出,之后它们将不再重新连接。在这里浏览似乎可能是因为没有正确处理管道对象,但我想这一切都很好,因为它们在 using 语句中。 有谁知道这里可能出了什么问题?代码在 .NET 4.0 中,在 windows server 2008 上运行。

【问题讨论】:

当您尝试同时从多个线程访问管道时会引发异常。管道不是线程安全的,你确定不是用两个线程同时访问它们吗? 创建多个调用 DoAction 的线程时,代码在第一次调用时崩溃,因为创建了第二个 NamedPipeServerStream(PIPE_TO) 实例。我尝试添加 lock(SyncToObject) 但仍然输入了两次代码。我认为因为它在单独的 AppDomain 中运行,但我不确定如何在单独的 Appdomains 中使用对象 你能把对 AppDomainCallback() 的调用移到任务中吗?还是因为它在另一个域中而在另一个线程上自动调用该方法? 确实是线程问题,谢谢。通过在 DoAction 的***别添加 lock(sync) 来修复它。对四个管道对象使用四个同步对象也可以,但它会使代码每隔一段时间停止一次 【参考方案1】:

听起来应该是mutex,而不是简单的锁

Lock, mutex, semaphore... what's the difference?

就偶尔的停止而言,可能是饥饿或死锁。

这是关于可能发生的事情的摘要的很好的阅读材料

http://en.wikipedia.org/wiki/Dining_philosophers_problem

【讨论】:

以上是关于C#所有管道实例都忙的主要内容,如果未能解决你的问题,请参考以下文章

C# 创建命名管道服务器

C# 进程通信-命名管道

获取使用 C# 连接到命名管道服务器的客户端的进程 ID

命名管道:C# 服务器、C++ 客户端

C#与C互传数据

命名管道客户端可以写入多个实例吗?