How to wait for a boolean without looping (using any kind of wait / semaphore / event / mutex, etc)

33,219

Solution 1

SpinWait.SpinUntil is the right answer, regardless where you're gonna place this code. SpinUntil offers "a nice mix of spinning, yielding, and sleeping in between invocations".

Solution 2

If you are using C# 4.0, you can use:

Task t = Task.Factory.StartNew (() => SomeCall(..));
t.Wait();

By using Task.Wait method.

If you have more than one task run one after another, you can use Task.ContinueWith:

 Task t = Task.Factory.StartNew (() =>SomeCall(..)).
                                ContinueWith(ExecuteAfterThisTaskFinishes(...);
 t.Wait();

Solution 3

declare as

 AutoResetEvent _ReadyToStop = new AutoResetEvent(false);

and use as

 _ReadyToStop.WaitOne();

and

 _ReadyToStop.Set();

For more info see the Synchronization Primitives in .Net

Share:
33,219
Ignacio Soler Garcia
Author by

Ignacio Soler Garcia

I am now acting as a delivery manager focused on the three main pillars of software creation: People, Procedures and Code working mainly with Javascript teams (React / Redux / Node) building applications 100% in the cloud with CI/CD, etc. I am open to proposals, let's talk. Previously I used to be an experienced technical leader commanding .Net technologies, passionate about Agile methodologies and a people person.

Updated on May 24, 2020

Comments

  • Ignacio Soler Garcia
    Ignacio Soler Garcia almost 4 years

    I need to stop a thread until another thread sets a boolean value and I don't want to share between them an event.

    What I currently have is the following code using a Sleep (and that's the code I want to change):

    while (!_engine.IsReadyToStop())
    {
        System.Threading.Thread.Sleep(Properties.Settings.Default.IntervalForCheckingEngine); 
    }
    

    Any ideas?

    EDIT TO CLARIFY THINGS:

    There is an object called _engine of a class that I don't own. I cannot modify it, that's why I don't want to share an event between them. I need to wait until a method of that class returns true.

    • Tudor
      Tudor over 11 years
      Why don't you want to share an event? There are two ways to do what you want: events or spinning.
    • L.B
      L.B over 11 years
      You want to share a boolean value but not an event. Why? What is the difference?
    • L.B
      L.B over 11 years
      I need to wait until a method of that class returns true. So what do you expect from us. Just loop as you already do.
    • Ignacio Soler Garcia
      Ignacio Soler Garcia over 11 years
      The title of the question is crystal clear I think: How to wait for a boolean without looping. If that cannot be done a "you cant'" will be the right answer. I'm not sure if this can or cannot be done.
    • L.B
      L.B over 11 years
      OK you get the answer. No you can't
    • Tudor
      Tudor over 11 years
      @SoMoS: But what is going on inside that method? Is it spawning a thread?
    • Ignacio Soler Garcia
      Ignacio Soler Garcia over 11 years
      @Tudor: yeah, the engine runs on its own thread.
    • Tudor
      Tudor over 11 years
      Well if you cannot change that class and the only way it communicates termination is with that boolean then I'm afraid you can't do anything but this spinning.
    • Martin James
      Martin James over 11 years
      It would have been friendlier if the 'engine' thing had called an 'OnReadyToStop' event, instead of supplying this silly polling method, but you seem to be stuck with it. Really need an engine rebuild..
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 11 years
    Ready to stop is a method that returns a boolean and that method is used at several places, that's why I said that I don't want to share an event between them, so as far as I know your answer is not valid.
  • L.B
    L.B over 11 years
    @SoMoS funny, then use another name
  • Tudor
    Tudor over 11 years
    What is the point of spawning a task and immediately joining it? And I don't think this was the OP's question.
  • David W
    David W over 11 years
    ReadyToStop is just the name he gave to the AutoResetEvent variable.
  • Tigran
    Tigran over 11 years
    @Tudor: I had a doubt on this too, so add add also explanation about ContinueWith
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 11 years
    I hope that now the question is more clear. My bad if it was not at the fist shot.
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 11 years
    I hope that now the question is more clear. My bad if it was not at the fist shot.
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 11 years
    As the problem is not waiting a task to end but waiting until a value is set I think the proposed solution is not applicable. Makes sense?
  • Tigran
    Tigran over 11 years
    @SoMoS: as your request is only waiting for the bollean change, that answer of L.B makes more sence. Just at the moment you set the boolean, Set event from the thread.
  • Tigran
    Tigran over 11 years
    @SoMoS: like stuff for readin can have a look on really comprehensive guide: Threading in C# of LinqPad creator.
  • Ignacio Soler Garcia
    Ignacio Soler Garcia over 6 years
    Not as good as a lock but seems the only possible way of doing it currently and much better that manually waiting.
  • StaceyGirl
    StaceyGirl about 6 years
    .NET has monitors separate condition variable is not needed, unless you need to share multiple condition variables with the same lock, but I doubt this is what OP needs.