2014-12-11 5 views
0

У меня есть следующая проблема с синхронизацией:C# Какой класс синхронизации использовать?

Несколько нитей выборочно проверяют, выполнено ли какое-либо условие. Если контрольная нить обнаруживает, что условие не выполнено, оно должно блокироваться, пока другой поток не выполнит условие и тем самым освободит все ожидающие/заблокированные потоки.

Имеет ли .NET такой класс syncrhonizing, который я могу использовать? Или мне придется создать собственный класс синхронизации поверх чего-то еще?

Что мне нужно, это просто семафоров как класс только с этими двумя методами:

  • BOOL Wait (TimeSpan maxTimeToWait) // блокирует любую caling нить, пока другой поток не вызывает сигнала() (или тайм-аут - возвращаемое значение покажет, что произошло)

  • void Signal() // выпускает все ожидающие темы.

С уважением, Мартин.

+0

http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent%28v=vs.110%29.aspx? – bas

+0

Это звучит как задание для [Класс монитора] (http://msdn.microsoft.com/en-us/library/system.threading.monitor%28v=vs.110%29.aspx). –

+0

Для этого можно использовать почти все примитивы synchzatıon, но неясно, что вы действительно хотите сделать. Возможно, могут быть лучшие способы, чем говорить * использовать это *. (Например, «Множественные потоки, случайно проверяющие, выполняется ли какое-либо условие», могут не понадобиться и могут быть просто реализованы с помощью примитивов синхронизации) –

ответ

1

EventWaitHandle звучит так, как будто вы ищите. Имейте в виду, что по мере того, как вы попадаете в такие конкретные реализации, вам может быть лучше сделать класс-оболочку делать то, что вы хотите, подключаясь к разрозненным классам .NET, которые выполняют те части, которые вы хотите.

Используя поведение автоматического сброса настроек вы можете сделать ручку, которая запускаемая каждый раз, когда что-то об упомянутом состоянии меняет, а затем выполнить while петли с условием

EventWaitHandle ConditionHandle 
//... 
while(!condition) 
    ConditionHandle.WaitOne(); 
0

AutoResetEvent делает то, что вы просить.

Ах. Я неправильно понял то, что вы просили. ManualResetEvent или ManualResetSlim будут пропускать все блокирующие потоки, но вам нужно будет сбросить MRE до беззнакового вручную.

+0

Согласно документации, AutoResetEvent выдает только один ожидающий поток при вызове Set(). Мне нужно, чтобы все ожидающие потоки были выпущены. –

+1

@MartinChristiansen На самом деле «Устанавливает состояние события для сигнализации, позволяя продолжить выполнение следующих ** или более ** ожидающих потоков. (Унаследовано от EventWaitHandle.)« – David

+0

@Aravol: В примечаниях вы можете прочитать: «Вызов Set signal AutoResetEvent чтобы освободить ожидающий поток. AutoResetEvent остается сигналом до тех пор, пока ** не будет отпущен ни один ** ожидающий поток, а затем автоматически вернется в состояние без сигнализации.Если никакие нити не ждут, состояние остается сигнализированным бесконечно ». Именно из-за этого я предположил, что будет выпущен только один ожидающий поток. –

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