Reputation: 58
Please consider code below. Each time I run the code, output will be always 0 and 3. I am sure it has something to do with single instance but didn't have any explanation why this is happening. It will be great if you can help me understand this. Thank you for your help.
Is this happening because variable points to a different location in heap each time we initialize it ?
public class Helper
{
List<int> list = new List<int>();
public List<int> GetList
{
get
{
return list;
}
}
public async Task<bool> Process()
{
await Task.Delay(1);
//sleep this thread for 6 seconds
Thread.Sleep(6000);
//When I debug, both of the thread adds into the list
//but first thread always have zero element on this list, if it adds to the list then where it is getting lost ?
//not sure why ? Has to do something with the variable below _confighelper
//but why it behaves likes this ? what would be the best explanation?
//where this variable is getting lost ?
list.Add(1);
list.Add(2);
list.Add(3);
return true;
}
}
public class RunOp
{
//Has to do something with single instance
Helper _configHelper;
public async Task Run()
{
_configHelper = new Helper();
var val = await _configHelper.Process();
Console.WriteLine(_configHelper.GetList.Count);
}
}
class Program
{
static void Main(string[] args)
{
RunOp op = new RunOp();
Task.Factory.StartNew(async () =>
{
await op.Run();
});
Thread.Sleep(4000);
//Start another thread after 4 seconds
Task.Factory.StartNew(async () =>
{
await op.Run();
});
Console.ReadLine();
}
}
Upvotes: 4
Views: 177
Reputation: 81573
This is a simple case of thread safety, and this is not thread safe
The problem is RunOp
has an internal Helper
, which gets overwritten and showing (what seems) inconsistent results because of the thread sleeps and delays.
Here is a thread safe version
public class RunOp
{
private SemaphoreSlim slim = new SemaphoreSlim(1,1);
//Has to do something with single instance
Helper _configHelper;
public async Task Run()
{
await slim.WaitAsync();
_configHelper = new Helper();
var val = await _configHelper.Process();
Console.WriteLine(_configHelper.GetList.Count);
slim.Release();
}
// or
public async Task Run()
{
Helper configHelper = new Helper();
var val = await configHelper.Process();
Console.WriteLine(configHelper.GetList.Count);
}
}
I know this is only an academic problem, but this really should be refactored and thought through again
Upvotes: 2