В моем цикле Parallel.Foreach я звоню
_helper.subscribeUserEndPoint(loop._contactGrpSvcs);
_helper — это класс инкапсуляции для UserEndPoint и всех других операций, таких как подписка.
Методы подписки:
public void subscribeUserEndPoint(ContactGroupServices cntGrpSvcs)
{
cntGrpSvcs.BeginSubscribe(TerminateSubscribe, cntGrpSvcs);
_contactSubscribeCompleted.WaitOne();
LOG.Info("Returning from Successful Subscribe Endpoint");
}
private void TerminateSubscribe(IAsyncResult result)
{
ContactGroupServices cntGrpSvcs = result.AsyncState as ContactGroupServices;
try
{
cntGrpSvcs.EndSubscribe(result);
}
catch (Exception ex)
{
LOG.Error("Failed to Complete Subscribe. " + ex.StackTrace);
}
CollaborationSubscriptionState state = cntGrpSvcs.CurrentState;
LOG.Info("Subscribed State = " + state.ToString());
_contactSubscribeCompleted.Set();
}
Взаимная блокировка потоков при ожидании _contactSubscribeCompleted.WaitOne(); Как избежать этой тупиковой ситуации?
Ваше здоровье,
-- Brian
PS: Одной из причин, по которой могут возникать взаимоблокировки, является внутренняя проблема с AutoResetEvent. Из документации: «Нет гарантии, что каждый вызов метода Set освобождает поток. Если два вызова слишком близки друг к другу, так что второй вызов происходит до того, как поток будет освобожден, освобождается только один поток. Это как если бы второй вызов не происходил. Кроме того, если Set вызывается, когда нет ожидающих потоков, а AutoResetEvent уже сигнализируется, вызов не имеет никакого эффекта." Есть ли обходной путь для этого ??
TerminateSubscribe
никогда не пытается взять конкурирующую блокировку. - person Marc Gravell   schedule 06.06.2012cntGrpSvcs.EndSubscribe(cntGrpSvcs.BeginSubscribe(null, null))
? (плюс некоторая обработка/регистрация исключений) - person Mike Zboray   schedule 07.06.2012