2013-08-26 4 views
7

Следующий код создает новый поток, действующий сначала как клиент именованного канала для отправки параметров, а затем в качестве сервера для получения результатов. После этого он выполняет функцию в другом AppDomain, выступая в качестве именованного канала, и после этого в качестве клиента отправляет результаты обратно.C# все экземпляры труб заняты

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 все экземпляры труб заняты» бросается, и после этого они больше не пересоединяются. Просмотр здесь кажется, что это может быть из-за неправильного удаления объектов трубопровода, но я думаю, что все хорошо, поскольку они находятся внутри с помощью утверждений. Кто-нибудь знает, что здесь может быть не так? Код в .NET 4.0 работает на сервере Windows 2008.

+3

Исключение брошено при попытке получить доступ к трубе из нескольких потоков одновременно. Трубы не являются потокобезопасными, уверены, что вы не обращаетесь к ним одновременно с двумя потоками? – hcb

+0

при создании нескольких потоков, которые вызывают DoAction, код вызывает сбой при первом вызове, потому что создается второй экземпляр NamedPipeServerStream (PIPE_TO). Я попытался добавить блокировку (SyncToObject), но код вводится дважды. Я думаю, потому что он работает в отдельной AppDomain, но я не уверен, как использовать объекты в отдельных Appdomains. – Laurijssen

+0

Можете ли вы переместить вызов AppDomainCallback() в задачу? Или этот метод автоматически вызван другим потоком, потому что он находится в другом домене? – hcb

ответ

1

Похоже, она должна быть mutex вместо простого замка

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

, насколько случайной остановке, это может быть голодание или тупик.

Это хороший материал для чтения для рефератов на то, что может происходить

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

Смежные вопросы