patterncsharpMinor
Determining if current thread is executing
Viewed 0 times
executingdeterminingthreadcurrent
Problem
Using C#, create a class which gets an action (parameter-less
delegate) in its construction and has a single public method
-
Executes the action only if no other thread is currently executing the action
-
If another thread is already executing, wait until thread is finished before returning (but without executing action again)
-
Return true if current thread executes that action, otherwise return false.
Is the above piece of code correct? Please give me your feedback.
Please don't think that this is just exercise. This question was asked by one of the interviewers.
delegate) in its construction and has a single public method
bool
execute() which does the following:-
Executes the action only if no other thread is currently executing the action
-
If another thread is already executing, wait until thread is finished before returning (but without executing action again)
-
Return true if current thread executes that action, otherwise return false.
public delegate bool Action();
private static int ThreadsCount = 100; //initialize threads count
static void Main(string[] args)
{
Action act = Execute;
bool t = act();
Console.WriteLine(t);
Console.ReadLine();
}
static bool Execute()
{
bool retVal = false;
Thread thread = Thread.CurrentThread;
string s = thread.Name;
if (s == null)
{
test();
retVal = true;
}
else
{
ThreadsCount = ThreadsCount - 1;
if (ThreadsCount < 1)
{
//if all threads finished executing do whatever you wanna do here..
Console.WriteLine("C# language");
test();
retVal = true;
}
else
{
retVal = false;
}
}
return retVal;
}
private static void test()
{
Console.WriteLine("C# language");
}Is the above piece of code correct? Please give me your feedback.
Please don't think that this is just exercise. This question was asked by one of the interviewers.
Solution
You need to look at how you can make the
Now, what this class provides is a wrapper around an
The
If if hasn't executed, it will
After the lock, we check whether the
If we are the first thread to be executing the delegate, we can then execute it
Any subsequent calls will always result in false.
To use in code:
Should result in:
Execute method both thread-safe and true to the requirements of the method. You say that it only should return true in the case where the delegate is actually called, but you need to make sure that only one thread can call it at a time. That's where lock comes in. You could potentially do something like:public class SingleCallAction
{
private readonly object sync = new object();
private readonly Action action;
private bool executed;
public SingleCallAction(Action action)
{
if (action == null)
throw new ArgumentNullException("action");
this.action = action;
}
public bool Execute()
{
if (!executed)
{
lock(sync)
{
if (!executed)
{
action();
executed = true;
return true;
}
}
}
return false;
}
}Now, what this class provides is a wrapper around an
Action delegate. We use Action because it supports both delegate assignment, or lambda assignment.The
Execute method will first check to see if it has previously been executed (if it has, it will jump down to the return false; as its not the thread that has executed the delegate.If if hasn't executed, it will
lock the sync object to prevent any other threads from executing the inner code block. The compiler is generating Monitor.Enter and Monitor.Exit calls here for you, worth a read up!After the lock, we check whether the
executed flag is set again. This allows us to prevent race conditions for competing threads. Don't worry about race conditions when dealing with the executed flag, as variable reads/writes are always atomic operations (mostly).If we are the first thread to be executing the delegate, we can then execute it
action(), set the flag as executed, and return true.Any subsequent calls will always result in false.
To use in code:
var action = new SingleCallAction(() => Console.WriteLine("Executed"));
var thread1 = new Thread(() => Console.WriteLine(action.Execute()));
var thread2 = new Thread(() => Console.WriteLine(action.Execute()));
thread1.Start();
thread2.Start();Should result in:
Executed
True
FalseCode Snippets
public class SingleCallAction
{
private readonly object sync = new object();
private readonly Action action;
private bool executed;
public SingleCallAction(Action action)
{
if (action == null)
throw new ArgumentNullException("action");
this.action = action;
}
public bool Execute()
{
if (!executed)
{
lock(sync)
{
if (!executed)
{
action();
executed = true;
return true;
}
}
}
return false;
}
}var action = new SingleCallAction(() => Console.WriteLine("Executed"));
var thread1 = new Thread(() => Console.WriteLine(action.Execute()));
var thread2 = new Thread(() => Console.WriteLine(action.Execute()));
thread1.Start();
thread2.Start();Executed
True
FalseContext
StackExchange Code Review Q#2910, answer score: 4
Revisions (0)
No revisions yet.