Следующий код создает новый поток, действующий сначала как клиент именованного канала для отправки параметров, а затем в качестве сервера для получения результатов. После этого он выполняет функцию в другом 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.
Исключение брошено при попытке получить доступ к трубе из нескольких потоков одновременно. Трубы не являются потокобезопасными, уверены, что вы не обращаетесь к ним одновременно с двумя потоками? – hcb
при создании нескольких потоков, которые вызывают DoAction, код вызывает сбой при первом вызове, потому что создается второй экземпляр NamedPipeServerStream (PIPE_TO). Я попытался добавить блокировку (SyncToObject), но код вводится дважды. Я думаю, потому что он работает в отдельной AppDomain, но я не уверен, как использовать объекты в отдельных Appdomains. – Laurijssen
Можете ли вы переместить вызов AppDomainCallback() в задачу? Или этот метод автоматически вызван другим потоком, потому что он находится в другом домене? – hcb