C# "ref" not Doing what I Think it Should - c#

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;
}
}
}

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.

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.

Related

(C# Value Doesnt Change) Modifiying Static Variables from Static Callback Method

Hello i want to ask how to modifiying value static variable from static callback, and read value again. I need to stop while looping when value from static variable change. This is my code.
The problem is value from stepControlEx remain same, it doesnt change when another callback run again and modify the value. It makes my looping stuck and cannot end.
Thanks for helping
Private static int stepControl = 0;
Private static int stepControlEx
{
get { return stepControl;}
set { stepControl = value;}
}
Private static void CallbackHandle (Object object)
{
If (object == 0)
{
stepControlEx = 0;
While (stepControlEx == 0)
{
//do events
//stop when stepControl Change
}
}
Else If (object == 1)
{
stepControlEx = 1;
While (stepControlEx == 1)
{
//do events
//stop when stepControl Change
}
}
}
EDITED (SOLVED):
I tottaly change the algorithm and use thread that process data from queue. Callback function only enqueue input to queue and thread dequeue input to processing, now step control doesn't need as global variable. Thank you
Your code looks ambiguous. But I have only one comment for your code. If you have a static variable and shared among multiple threads, you need to lock the variable while changing it.
I think you get deadlocks that is why the loop never ends.
Anytime you assign any static variable in a multi-threading environment. you need to to this:
lock (new object())
{
stepControlEx = 0;
}

Class Variable UnChanged by Asyncronous Method

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?
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.
You can use Thread.Yield() in the loop.
do
{
string busyWork = "";
Thread.Yield();
}
while (thingIsDone == false)

Avoid repetitive calls to a Routine from Multiple Threads within a win form?

I have a Private object variable within a Windows form which has performs the tcp/IP socket connection and keeps the connection opened.
On form_load this object is initialized and the form has 15-20 Threads running continously within it which access this object. There are scenarios where in which the Tcp/Ip connection might be lost. SO whenever i find that the connection is lost i call the ReconnectToSocket() Method within the thread. I am performing the below code to ensure that the ReconnectToSocket() method is only called once by using _ReconnectingSocket property. But after checking the Text Log files i found out that this method is called within each sub thread's.
How can i make sure that this method is called only once and avoid repetitive calls.
Below is my code. I am interested in any alternative approach, because i feel that this is not the right approach in doing so.
bool _bReconnectingSocket = false;//To check if it is currently reconnecting
readonly object lock_reconnectSocket = new object();
private bool _ReconnectingSocket
{
get
{
lock (lock_reconnectSocket)
{
return this._bReconnectingSocket;
}
}
set
{
lock (lock_reconnectSocket)
{
this._bReconnectingSocket = value;
}
}
}
private void ReconnectToSocket()
{
if (!this._ReconnectingSocket)
{
this._ReconnectingSocket = true;
//Each sub thread checks for this variable while looping and exits from the infinite loop
this._Stop = true;
//Join all the Sub Threads Before Reconnecting
foreach (SocketThread thrd in this._subThreadCol)
{
try
{
this._objLog.WriteInfo(string.Format("Joining Subthread - {0} for Reconnecting.", thrd.ThrdID));
thrd.Join();
}
catch { }
}
this.ConnectSocket();
this._ReconnectingSocket = false;
this._Stop = false;
}
}
Try to write something like that in your class. Your routine still might be called several times, but its actual body will be executed only once at a time, if reconnected field is false.
bool reconnected = false;
object lockObject = new object();
void ReconnectToSocket()
{
lock(lockObject)
{
if(!reconnected) { /*do stuff*/; reconnected = true; }
}
}
Hi the object you lock against should be static private of the class and not an instance member. One thing I am not sure about is why you are sharing same connection among threads instead of having each thread to open, consume and immediately close its own one like we would do with a SqlConnection.

Interlocked used to increment/mimick a boolean, is this safe?

I'm just wondering whether this code that a fellow developer (who has since left) is OK, I think he wanted to avoid putting a lock. Is there a performance difference between this and just using a straight forward lock?
private long m_LayoutSuspended = 0;
public void SuspendLayout()
{
Interlocked.Exchange(ref m_LayoutSuspended, 1);
}
public void ResumeLayout()
{
Interlocked.Exchange(ref m_LayoutSuspended, 0);
}
public bool IsLayoutSuspended
{
get { return Interlocked.Read(ref m_LayoutSuspended) != 1; }
}
I was thinking that something like that would be easier with a lock? It will indeed be used by multiple threads, hence why the use of locking/interlocked was decided.
Yes what you are doing is safe from a race point of view reaching the m_LayoutSuspended field, however, a lock is required for the following reason if the code does the following:
if (!o.IsLayoutSuspended) // This is not thread Safe .....
{
o.SuspendLayout(); // This is not thread Safe, because there's a difference between the checck and the actual write of the variable a race might occur.
...
o.ResumeLayout();
}
A safer way, that uses CompareExchange to make sure no race conditions have occurred:
private long m_LayoutSuspended = 0;
public bool SuspendLayout()
{
return Interlocked.CompareExchange(ref m_LayoutSuspended, 1) == 0;
}
if (o.SuspendLayout())
{
....
o.ResumeLayout();
}
Or better yet simply use a lock.
Personally I'd use a volatile Boolean:
private volatile bool m_LayoutSuspended = false;
public void SuspendLayout()
{
m_LayoutSuspended = true;
}
public void ResumeLayout()
{
m_LayoutSuspended = false;
}
public bool IsLayoutSuspended
{
get { return m_LayoutSuspended; }
}
Then again, as I've recently acknowledged elsewhere, volatile doesn't mean quite what I thought it did. I suspect this is okay though :)
Even if you stick with Interlocked, I'd change it to an int... there's no need to make 32 bit systems potentially struggle to make a 64 bit write atomic when they can do it easily with 32 bits...

Thread-safe use of a singleton's members

I have a C# singleton class that multiple classes use. Is access through Instance to the Toggle() method thread-safe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
public class MyClass
{
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private int value = 0;
public int Toggle()
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}
Is access through 'Instance' to the 'Toggle()' class threadsafe? If yes, by what assumptions, rules, etc. If no, why and how can I fix it?
No, it's not threadsafe.
Basically, both threads can run the Toggle function at the same time, so this could happen
// thread 1 is running this code
if(value == 0)
{
value = 1;
// RIGHT NOW, thread 2 steps in.
// It sees value as 1, so runs the other branch, and changes it to 0
// This causes your method to return 0 even though you actually want 1
}
else if(value == 1)
{
value = 0;
}
return value;
You need to operate with the following assumption.
If 2 threads are running, they can and will interleave and interact with eachother randomly at any point. You can be half way through writing or reading a 64 bit integer or float (on a 32 bit CPU) and another thread can jump in and change it out from underneath you.
If the 2 threads never access anything in common, it doesn't matter, but as soon as they do, you need to prevent them from stepping on each others toes. The way to do this in .NET is with locks.
You can decide what and where to lock by thinking about things like this:
For a given block of code, if the value of something got changed out from underneath me, would it matter? If it would, you need to lock that something for the duration of the code where it would matter.
Looking at your example again
// we read value here
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
// and we return it here
return value;
In order for this to return what we expect it to, we assume that value won't get changed between the read and the return. In order for this assumption to actually be correct, you need to lock value for the duration of that code block.
So you'd do this:
lock( value )
{
if(value == 0)
... // all your code here
return value;
}
HOWEVER
In .NET you can only lock Reference Types. Int32 is a Value Type, so we can't lock it.
We solve this by introducing a 'dummy' object, and locking that wherever we'd want to lock 'value'.
This is what Ben Scheirman is referring to.
The original impplementation is not thread safe, as Ben points out
A simple way to make it thread safe is to introduce a lock statement. Eg. like this:
public class MyClass
{
private Object thisLock = new Object();
private static readonly MyClass instance = new MyClass();
public static MyClass Instance
{
get { return instance; }
}
private Int32 value = 0;
public Int32 Toggle()
{
lock(thisLock)
{
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
return value;
}
}
}
I'd also add a protected constructor to MyClass to prevent the compiler from generating a public default constructor.
That is what I thought. But, I I'm
looking for the details... 'Toggle()'
is not a static method, but it is a
member of a static property (when
using 'Instance'). Is that what makes
it shared among threads?
If your application is multi-threaded and you can forsee that multiple thread will access that method, that makes it shared among threads. Because your class is a Singleton you know that the diferent thread will access the SAME object, so be cautioned about the thread-safety of your methods.
And how does this apply to singletons
in general. Would I have to address
this in every method on my class?
As I said above, because its a singleton you know diferent thread will acess the same object, possibly at the same time. This does not mean you have to make every method obtain a lock. If you notice that a simultaneos invocation can lead to corrupted state of the class, then you should apply the method mentioned by #Thomas
Can I assume that the singleton pattern exposes my otherwise lovely thread-safe class to all the thread problems of regular static members?
No. Your class is simply not threadsafe. The singleton has nothing to do with it.
(I'm getting my head around the fact that instance members called on a static object cause threading problems)
It's nothing to do with that either.
You have to think like this: Is it possible in my program for 2 (or more) threads to access this piece of data at the same time?
The fact that you obtain the data via a singleton, or static variable, or passing in an object as a method parameter doesn't matter. At the end of the day it's all just some bits and bytes in your PC's RAM, and all that matters is whether multiple threads can see the same bits.
Your thread could stop in the middle of that method and transfer control to a different thread. You need a critical section around that code...
private static object _lockDummy = new object();
...
lock(_lockDummy)
{
//do stuff
}
I was thinking that if I dump the singleton pattern and force everyone to get a new instance of the class it would ease some problems... but that doesn't stop anyone else from initializing a static object of that type and passing that around... or from spinning off multiple threads, all accessing 'Toggle()' from the same instance.
Bingo :-)
I get it now. It's a tough world. I wish I weren't refactoring legacy code :(
Unfortunately, multithreading is hard and you have to be very paranoid about things :-)
The simplest solution in this case is to stick with the singleton, and add a lock around the value, like in the examples.
Quote:
if(value == 0) { value = 1; }
if(value == 1) { value = 0; }
return value;
value will always be 0...
Well, I actually don't know C# that well... but I am ok at Java, so I will give the answer for that, and hopefully the two are similar enough that it will be useful. If not, I apologize.
The answer is, no, it's not safe. One thread could call Toggle() at the same time as the other, and it is possible, although unlikely with this code, that Thread1 could set value in between the times that Thread2 checks it and when it sets it.
To fix, simply make Toggle() synchronized. It doesn't block on anything or call anything that might spawn another thread which could call Toggle(), so that's all you have to do save it.

Categories