Suppose I have two threads, thread A and thread B. What happens in C# when thread A sets an object, call it object X, to a value, and thread B comes along and tries to fetch that object while it is getting set by thread A? Would C# throw an exception, would B receive object X before A makes changes to it, or would B receive object X after A makes changes to it?
I thought it was clear, but here is the code (and even with added synchronization I am still not 100% sure that this would cause the exact case I mentioned above to occur):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication8 {
public partial class Form1 : Form {
private AutoResetEvent waitEvent = new AutoResetEvent(false);
int objectX = 0;
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
DateTime startTime = DateTime.Now;
Console.WriteLine("---------------------------- START @ " + startTime + " ----------------------------------------------------------------------");
Thread A = new Thread(ThreadAWorkMethod);
Thread B = new Thread(ThreadBWorkMethod);
objectX = 0;
waitEvent = new AutoResetEvent(false);
A.Start();
B.Start();
A.Join();
B.Join();
Console.WriteLine("---------------------------- FINISHED AFTER " + (DateTime.Now - startTime).TotalMilliseconds + " ----------------------------");
}
public void ThreadAWorkMethod() {
waitEvent.WaitOne();
objectX = 5;
Console.WriteLine("Value has been changed to: " + objectX + " in thread A at " + DateTime.Now);
return;
}
public void ThreadBWorkMethod() {
waitEvent.Set();
string xInThreadB = objectX.ToString();
Console.WriteLine("Value in thread B: " + xInThreadB + " at " + DateTime.Now);
return;
}
}
}
The output of thread B to the console looks to be either 0 or 5, but even still you cannot say for certain which thread got serviced first even by checking the DateTime because both threads will have identical timestamps…and one output always makes it to the console first, so whose to say which got serviced first and if the threads actually collided on a get-set. So, in the end it seems that locking is implemented on variables in C# from a lower framework level as some people have mentioned.
No, it will likely not. There is nothing in the runtime that will check for this condition automatically and raise an exception.
However, the “value” being set may or may not be in a valid state at that point, so as soon as the result is used, whatever uses the value could easily raise an exception.
Either is possible. It’s also possible, depending on the type of “object”, that B would receive the object in an invalid state.
If you know multiple threads will be accessing a value, you should always take care to synchronize the access to your property. There are many options for synchronization, from using the (relatively) simple
lockstatement to other more complex synchronization options (such asReaderWriterLock/ReaderWriterLockSlim,Mutex,Semaphore, etc).