c# - tipos - Cómo esperar un booleano sin bucle(utilizando cualquier tipo de esperar/semáforo/evento/mutex, etc.)
glosario c# (4)
Si está utilizando C# 4.0
, puede usar:
Task t = Task.Factory.StartNew (() => SomeCall(..));
t.Wait();
Utilizando el método Task.Wait .
Si tiene más de una tarea ejecutada una después de otra, puede usar Task.ContinueWith :
Task t = Task.Factory.StartNew (() =>SomeCall(..)).
ContinueWith(ExecuteAfterThisTaskFinishes(...);
t.Wait();
Necesito detener un hilo hasta que otro hilo establezca un valor booleano y no quiero compartir entre ellos un evento .
Lo que actualmente tengo es el siguiente código que usa un Sleep (y ese es el código que quiero cambiar):
while (!_engine.IsReadyToStop())
{
System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine);
}
¿Algunas ideas?
EDITAR PARA CLARIFICAR LAS COSAS:
Hay un objeto llamado _engine de una clase que no tengo. No puedo modificarlo, por eso no quiero compartir un evento entre ellos. Necesito esperar hasta que un método de esa clase devuelva verdadero.
Una variable de condición es la primitiva de sincronización que puede usar para esperar en una condición.
No existe de forma nativa en .NET. Pero el siguiente link proporciona un código 100% administrado para una clase de variable de condición implementada en términos de las clases SemaphoreSlim, AutoResetEvent y Monitor. Permite que el hilo espere en una condición. Y puede despertar uno o más hilos cuando se cumple la condición. Además, soporta tiempos de espera y cancelaciónTokens.
Para esperar en una condición usted escribe un código similar al siguiente:
object queueLock = new object();
ConditionVariable notEmptyCondition = new ConditionVariable();
T Take() {
lock(queueLock) {
while(queue.Count == 0) {
// wait for queue to be not empty
notEmptyCondition.Wait(queueLock);
}
T item = queue.Dequeue();
if(queue.Count < 100) {
// notify producer queue not full anymore
notFullCondition.Pulse();
}
return item;
}
}
Luego, en otro hilo, puedes despertar uno o más hilos en espera.
lock(queueLock) {
//..add item here
notEmptyCondition.Pulse(); // or PulseAll
}
declarar como
AutoResetEvent _ReadyToStop = new AutoResetEvent(false);
y usar como
_ReadyToStop.WaitOne();
y
_ReadyToStop.Set();
Para más información vea las Primitivas de Sincronización en .Net
SpinWait.SpinUntil
es la respuesta correcta, independientemente de dónde colocarás este código. SpinUntil ofrece "una buena mezcla de hilado, rendimiento y durmiendo entre invocaciones" .