Je dois arrêter un thread jusqu'à ce qu'un autre thread définisse une valeur booléenne et je ne souhaite pas partager entre eux un événement .
Ce que j'ai actuellement est le code suivant utilisant un sommeil (et c'est le code que je veux changer):
while (!_engine.IsReadyToStop())
{
System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine);
}
Des idées?
Editer pour clarifier les choses:
Il y a un objet appelé _engine d'une classe que je ne possède pas. Je ne peux pas le modifier, c'est pourquoi je ne veux pas partager un événement entre eux. J'ai besoin d'attendre qu'une méthode de cette classe retourne true.
SpinWait.SpinUntil
est la bonne réponse, peu importe où vous allez placer ce code. SpinUntil offre "un joli mélange de rotation, de rendement et de sommeil entre les invocations" .
Si vous utilisez C# 4.0
, vous pouvez utiliser:
Task t = Task.Factory.StartNew (() => SomeCall(..));
t.Wait();
En utilisant Task.Wait méthode.
Si vous avez plusieurs tâches exécutées l'une après l'autre, vous pouvez utiliser Task.ContinueWith :
Task t = Task.Factory.StartNew (() =>SomeCall(..)).
ContinueWith(ExecuteAfterThisTaskFinishes(...);
t.Wait();
déclarer comme
AutoResetEvent _ReadyToStop = new AutoResetEvent(false);
et utiliser comme
_ReadyToStop.WaitOne();
et
_ReadyToStop.Set();
Pour plus d'informations, voir Primitives de synchronisation dans .Net
Une variable de condition est la primitive de synchronisation que vous pouvez utiliser pour attendre une condition.
Il n’existe pas nativement dans .NET. Mais le link suivant fournit du code 100% géré pour une classe de variable de condition implémentée en termes de classes SemaphoreSlim, AutoResetEvent et Monitor. Cela permet au thread d'attendre une condition. Et peut réveiller un ou plusieurs threads lorsque la condition est remplie. En outre, il prend en charge les délais d’expiration et AnnulationTokens.
Pour attendre, vous écrivez un code semblable à celui-ci:
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;
}
}
Ensuite, dans un autre thread, vous pouvez réactiver un ou plusieurs threads en attente de condition.
lock(queueLock) {
//..add item here
notEmptyCondition.Pulse(); // or PulseAll
}