Can someone explain whether or not I can call the below class "thread safe"?
As far as I know, we can call something thread safe if we are not breaking existing functionality
Example:
public class BackgroundWorker
{
private readonly IDictionary<string, RunningTask> _runningTasks = new ConcurrentDictionary<string, RunningTask>();
/// <summary>
/// Executes async job for the specified key, only one at a time.
/// </summary>
/// <param name="key"></param>
public void Enqueue(string key)
{
if (_runningTasks.ContainsKey(key))
{
_runningTasks[key].Repeat = true;
return;
}
_runningTasks[key] = new RunningTask();
ExecuteTask(key);
}
private void ExecuteTask(string key)
{
Task.Run(() =>
{
// Do something
if (_runningTasks[key].Repeat)
{
_runningTasks[key].Repeat = false;
ExecuteTask(key);
return;
}
_runningTasks.Remove(key);
});
}
private class RunningTask
{
/// <summary>
/// Flag to repeat a task after completion.
/// </summary>
public bool Repeat { get; set; }
}
}
I don't think so because _runningTasks is shared object and your method Enqueue is writing on this shared object. For example its possible when one thread already executed line number y, another thread will evaluate condition check in line number x as true - which might not be intention.
public void Enqueue(string key)
{
if (_runningTasks.ContainsKey(key)) /*say line no : x */
{
_runningTasks[key].Repeat = true;
return;
}
_runningTasks[key] = new RunningTask(); /*say line no:y*/
ExecuteTask(key);
}
Using ConcurrentDictionary will just ensure no two threads can read/write to/from the dictionary same time.
To your second point :
As far as I know, we can call something thread safe if we are not breaking existing functionality
No this is not the definition of thread safe (might be ok to say one of desirable outcome in multi threaded environment) I would recommend to read this post for official meaning rather.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With