2

I have a class that talks to an external .exe. The class has a bunch of similar methods; they call a function of the .exe, wait for response, and then return true or false.

The response comes in the form of events that change the values of fields of this class.

Simplified code:

class Manager { private static bool connected = false; public static bool Connect() { runtime.Connect(); int secondsWaited = 0; while (!connected) { Thread.Sleep(1000); if (secondsWaited++ == 10) { return false; } } return true; } } 

The other methods use the same call-wait-loop-return structure.

My goal is to make a single method to do this waiting for me, like so:

private static bool WaitReferenceEqualsValue<T>(ref T reference, T value) { int secondsWaited = 0; while (!reference.Equals(value)) { Thread.Sleep(1000); if (secondsWaited++ == 10) { return false; } } return true; } 

Then each method would do:

runtime.DoSomething(); return WaitReferenceEqualsValue<someType>(ref someField, someSuccessfulValue); 

However, when I replace the wait-loop with this method call, the field "connected", even though passed in as a reference, always stays the same.

Any idea what's going on here, and how to get the desired functionality?

Thanks in advance.

EDIT:

public static bool Connect() { ... runtime.Connect(); // this code works /*int secondsWaited = 0; while (connected != true) { Thread.Sleep(1000); if (secondsWaited++ == 10) { return false; } }*/ // this somehow blocks OnConnect from firing, so connected never gets set to true lock (typeof(SkypeKitManager)) { WaitReferenceEqualsValue<bool>(ref connected, true); } ... } 

OnConnect:

private static void OnConnect(object sender, Events.OnConnectArgs e) { if (e != null && e.success) { lock (typeof(Manager)) { connected = true; } } } 
2
  • 2
    I don't see where you are re-assigning this value. You only seem to be testing with it...maybe you are missing some code? Commented Mar 7, 2013 at 19:59
  • Don't know if it is because of the example, but make sure to check for null before calling Equals on reference. Commented Mar 7, 2013 at 20:25

2 Answers 2

3

You're not doing any synchronization on that field although you access it from multiple threads and one of them is writing. This is a race (no exception! this is a race even if it looks safe. It isn't safe.).

Probably the JIT enregistered it which is a common optimization. It just never gets read from memory, always from a register. Add synchronization (for example a lock, or Interlocked or Volatile methods).

Your usage of ref is correct.

Sign up to request clarification or add additional context in comments.

6 Comments

One anonymous downvote for each answer? That's not good because we don't know what's wrong.
Huh. I added locks to all accesses to it (there are a connect and disconnect methods, and OnConnect and OnDisconnect events that set this field's value), but I see no change. In fact, the OnConnect event never fires just because this method is called.
Can you post the new code and all places where you set the value? Can you prove that the value is being set?
@usr, as Justin mentioned, the OP doesn't provide any code that "writes" a value. (on other threads or otherwise) Without seeing that, everything is wild speculation.
Edited and added the change and showed the OnConnect event, which sets the value of "connected".
|
2

The problem with your code is essentially compiler optimization. Fo optimization purpose compilers (or jits) necessarily take a pretty much single threaded view. The compiler/jit will then notice that you don't touch reference in your code at all, therefore it can move the comparison outside the loop. It is free to do so, since you basically create a race condition (no synchronization/atomic accesses).

Fixing it could either involve using synchronization mechanisms or add the volatile specifier to reference, thus telling the compiler/jit, that the variable can be changed from outside the method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.