8

The following code creates a new thread acting first as a named pipe client for sending parameters and then as a server for retrieving results. After that it executes a function in another AppDomain acting as a named pipe server and after that as a client to send the results back.

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);
  }
}

The code is called once per second on average and it worked fine for 7+ hours. But at some point "system.io.ioexception all pipe instances are busy" is thrown and they wont reconnect anymore after that. Browsing here it seems like it could be because of not properly disposing the pipe objects, but I guess thats all good since they are inside using statements. Does anyone have any clue what could be wrong here? The code is in .NET 4.0 running on windows server 2008.

Serve Laurijssen
  • 9,266
  • 5
  • 45
  • 98
  • 3
    The exception is thrown when you try to access a pipe from multiple threads at once. Pipes are not thread-safe, are you sure you don't access them simultaneously with the two threads? – hcb Aug 26 '13 at 06:52
  • when creating multiple threads that call DoAction the code crashes on the first call because a second NamedPipeServerStream(PIPE_TO) instance is made. I tried adding lock(SyncToObject) but the code is entered twice still. I think because it runs in a separate AppDomain but Im not sure how to use objects in separate Appdomains – Serve Laurijssen Aug 26 '13 at 07:40
  • Can you move the call to AppDomainCallback() in to the task? Or is that method automatically called on another thread because it's in another domain? – hcb Aug 26 '13 at 08:16
  • 1
    it was indeed a Thread issue, thanks. Fixed it by adding lock(sync) at the highest level, in DoAction. Using four sync objects for the four pipe objects worked too but it makes the code halt every once in a while – Serve Laurijssen Aug 26 '13 at 08:50

1 Answers1

2

Sounds like it should be a mutex instead of a simple lock

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

as far as the occasional halting, it could be starvation or a deadlock.

This is good reading material for abstracts on what may be happening

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

Community
  • 1
  • 1
Maslow
  • 18,464
  • 20
  • 106
  • 193