0

EDIT: I know this is bad code, that's why I tagged it with anti-pattern.

OK, so this is some actual real code I found today:

public class ServiceWrapper
{
    bool thingIsDone = false; //class variable.
    //a bunch of other state variables

    public string InvokeSoap(methodArgs args)
    {
        //blah blah blah
        soapClient client = new Client();
        client.doThingCompleted += new doThingEventHandler(MycompletionMethod);
        client.doThingAsync(args);

        do
        {
            string busyWork = "";
        }
        while (thingIsDone == false)

        //do some more stuff
    }

    private void MyCompletionMethod(object sender, completedEventArgs e)
    {
        //do some other stuff
        thingIsDone = true;
    }
}

OK, so I'm aware of why this is bad, obviously. But what's actually making me ask this question is, thingIsDone never seems to be true in the InvokeSoap method, even if set true in MyCompletionMethod, but only if complied in Release. It behaves as one would "expect" in Debug mode.

Adding Thread.Sleep(100) inside the while loop also fixes it. What's up with this?

Pharylon
  • 9,796
  • 3
  • 35
  • 59

2 Answers2

4

The CPU may cache the value of thingIsDone, since that thread cannot change it between reads.

You need volatile to force the writes to be published so the other thread can read it.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

You can use Thread.Yield() in the loop.

do
{
    string busyWork = "";
    Thread.Yield();
}
while (thingIsDone == false)
mehrandvd
  • 8,806
  • 12
  • 64
  • 111