Saturday, April 3, 2010
Multithreading - Task Synchronization - Barrier Class - C# 4.0
Formally, this class enables multiple tasks to cooperatively work on an algorithm in parallel through multiple phases. A Barrier enforces the stopping of execution between a number of threads preventing further execution until all threads have reached the given point. On other way, all threads may start their work independently but can not proceed beyond a certain point of time until other threads have not reached to that point.
This class reminds me the typical college trips (i.e. Trip will start from point X and everyone should meet at point X). Let’s see how this class achieve the stated functionality.
Assume there are 3 friends Tom, Tomm and Tommm (feel free to change ). On Friday night, they decided to go for a trip. So, they decided that we will meet at the Trip centre to enter the new city. To simplify the scenario, let’s assume either all 3 will go for the Trip or they will cancel the Trip. So, they registered their trip with the centre. Trip canter is responsible to tell the exact position of the trip members and give a signal to start or cancel the Trip.
So, here is your Trip centre and its token (say registration token):
static Barrier tripCenter;
static CancellationToken token;
Now, here is how registration will happen:
// Register 3 members to the Barrier
tripCenter = new Barrier(3);
Before we proceed further on Trip, let’s see what else this Barrier class has to offer during the registration:
1. Class offers the flexibility to increase or decrease the number of participants at any point of time after the registration process.
// Changed the plan. Let's make it five participants.
tripCenter.AddParticipants(2);
// 5th Person is in trouble and he is not joining us. Settle on 4.
tripCenter.RemoveParticipant();
2. You can ask for the notification once everyone has reached at the barrier. You can provide the Action at the time of registration. Here is what we will define for this trip
tripCenter = new Barrier(3, (barrier) =>
{
Console.WriteLine("Every One has Arrived. All of you [Total - {0} ] can proceed for your Trip now. My duty for phase {1} is over. Cheers.", barrier.ParticipantCount, barrier.CurrentPhaseNumber);
});
Next step is to provide the task to be executed by the participants before reaching at the barrier. This task is the set of actions performed by your workers (or threads). Here we go for the task:
static void MakeMyTrip(string name, TimeSpan timeToReachPetrolPump)
{
try
{
Console.WriteLine("[{0}] Leaving House", name);
// Perform some work
Thread.Sleep(timeToReachPetrolPump);
Console.WriteLine("[{0}] Arrived at Petrol Pump", name);
// Need to sync here
tripCenter.SignalAndWait(token);
// Perform some more work
Console.WriteLine("[{0}] Starting the Trip Now", name);
}
catch (OperationCanceledException)
{
Console.WriteLine("[{0}] Problem in Bike... Trip Cancelled!! Going
home!", name);
}
}
Let’s assume that things will go fine for this trip and ignore the Catch block for a while. We will discuss it shortly. As per the task:
1. Participant will leave the house and will reach at petrol pump.
2. Once they have reached at the Trip centre, they need to signal this event to barrier. (Inform Trip Centre that you have arrived).
3. No one can proceed further without the signal from the barrier.
4. How Barrier maintains this data is with every call to SignalAndWait(), the number of signals received by the barrier is incremented. Once the number of signals received reaches the number of participants the Barrier was constructed with, all threads are then allowed to continue execution.
And, the last step is to Activate your participant for the Trip.
var tom = new Thread(() => MakeMyTrip("tom", TimeSpan.FromSeconds(0)));
tom.Start();
var tomm = new Thread(() => MakeMyTrip("tomm", TimeSpan.FromSeconds(4)));
tomm.Start();
var tommm = new Thread(() => MakeMyTrip("tommm", TimeSpan.FromSeconds(6))); tommm.Start();
// Allow them to complete their trip
tom.Join();
tomm.Join();
tommm.Join();
If you will execute this program, you will observe that participants are leaving the home and reaching at the petrol pump in random order. But no one is allowed to proceed beyond the barrier until all participants are not ready. This class provides a god help otherwise we would have written code with Events (which involves manual intervention for the synchronization).
So far things are good as we assumed that there won’t be any problem to anyone and everyone will reach at the barrier. This is something not practical. There may be several scenarios when thread or worker may stop it’s execution (say data fault). In this case, worker may inform the other worker threads (participants in our case) about the cancellation of the Trip. And therefore, above untouched Catch block comes into the picture.
In the beginning, we have declared Barrier class reference along with reference of the class CancellationToken. This class provides the cancellation token for the given Barrier.
var source = new CancellationTokenSource();
// Get the Token
token = source.Token;
// Activate the Worker Threads
// Not Happy with the Idea, Cancel the Trip
source.Cancel();
Once the source has raised the alarm for cancel, OperationCanceledException exception will be raised to all waiting worker threads.
Finally, the action defined for the barrier. Once all participants have reached to the barrier, barrier will execute the action defined at the time of registration. In our, there is an announcement by the Trip Centre. This action will not be executed by the barrier if the Source has aborted the task (say when Trip is cancelled, there will be no announcement).
You saw that how we can use barrier for the synchronization of the tasks. But there are several other aspects which can be discussed here:
1. What will happen if any worker of the barrier has been aborted without any notice?
2. Will other threads throw time out exception or will wait indefinitely.
3. Can we define any time limit on each worker to reach at barrier?
I will keep these questions open for the discussion.
Sunday, February 28, 2010
Var data type and C# typing
Var data type and C# typing
Release of C# 3.0 was blessed with the new keyword ‘Var’. Var allows you to declare a new variable, whose type is implicitly inferred from the expression used to initialize the variable.
Question is: Does Var affect the typing of the languages? Does C# version 3.0 is less statically typed than its previous versions?
Answer is No. Var does not affect the typing status of the language. C# still remains a statically typed language.
Let’s consider the below statement:
| var x = "Sweet Var"; |
| No errors are present in this statement. |
Now, if we look at the definition of the dynamic type, it claims that ‘In Dynamic Type, Values have type but Variables do not’.
So, don’t you think above statement, makes the Var declaration a good candidate for dynamic typing?
Well, the answer is No. Look at the below statement:
| var x = "Sweet Var"; x = 1; |
| Error: Cannot implicitly convert type 'int' to 'string' |
It means, compiler has the complete knowledge of the data type of the variable X (inferred from the type of value it has). So, above statement is nothing but a wrapper provided to a lazy developer (Not always. It has good usage for Anonymous types and many more), somewhat similar to the Extension Methods (a good candidate for my next blog J). So, I can assume how compiler will process the Var statement:
| COMPILE: var x = "Sweet Var"; RAISE: GotALazyDeveloper(x, string); REPLACE: (var x, String x) COMPILE: Sting x = "Sweet Var"; |
| |
Tuesday, February 23, 2010
Updating Controls Data in Multithreaded Environment
If you are developing a multithreaded Windows application, there are high chances that data for a single control is being generated by many threads. In other words, any thread can raise a request to update the control which is owned by some other thread. If you are a .Net developer using .Net versions 2.0 onwards, accomplishing the request is not straight forward case. .Net 2.0 onwards, cross thread operations are not permitted (correct word - ‘advised’).
There are several ways in which you can accomplish this:
· This exception is raised by Visual Studio only. If you will run the application out of Visual Studio, CLR will never complain about the cross thread operation.
Therefore, you can use this simple (Bad though) syntax
Control.Data = data;
· If you are really worried about the testing team ( And not about the application ) that any tester might complain this error while testing the code through Visual Studio, then you can suppress this exception also. You need to instruct Visual Studio to shut up on any cross thread operation:
CheckForIllegalCrossThreadCalls = false;
· If you are concerned about the application and have sense of good programming, then I don’t think above two Options are good for you. One way is to use the invoke method on the control. Each control has a property [Control.InvokeRequired] which can tell you whether control has been created by the current thread or any other thread.
You can use Invoke method to update the control’s state.
| ** UpdateUIDel -> Delegate ** UpdateUI ->Method to update the controls’ state (i.e. text in a textbox). |
| delegate void UpdteUIDel(int a); private void UpdateUI(Object a) { textBox1.Text = a.ToString(); } |
| // Call Invoke on Form itself this.Invoke(new UpdteUIDel(UpdateUI), val); |
· Here is the last method which I think is the best way to solve the problem. .Net does provide SynchronizatinContext class for propagating a synchronization context in various synchronization models. For Windows forms, corresponding context class is the WindowsFormsSynchronizationContext which provides a synchronization context for the Windows Forms application model and is the child class of the SynchronizatinContext.
This class takes the responsibility to identify the control’s owner and updates the control via the same owner.
| WindowsFormsSynchronizationContext context = new WindowsFormsSynchronizationContext(); SendOrPostCallback updateDel = new SendOrPostCallback(UpdateUI); // Syncronous Method context.Send(updateDel, val); // Asynchronous Methods // context.Post(updateDel, val); |
| Send is synchronous call (similar to Invoke ) Post is asynchronous call (similar to BeginInvoke) |
Sunday, February 7, 2010
Interesting Question...
Question was: Guys tell me how to print both 'if' and 'else' block in a program..
{
int a=2;
A:
a--;
if(a>0)
{
/* write ur code */
goto A;
}
else
{
/* write ur code */
}
return 0;
}
Design Problem - Share the Common Instance of Base Class


Here is the problem statement (might sound weird):
There was no definite sequence of initialization of child classes.
I tried for sometime, but I could not stop the initialization of base class on child class instantiation. I was really wondering if there is any way to do this. I was failed to provide the code to support the design
(though bad)
· Today I was going through singleton implementation and suddenly I got one idea to implement the above discussed design.
Check Program.cs. [Here, Utility is class ‘Use’]
Still I am not sure when any one will go for such design.
public class Program
{
public static void Main()
{
ChildSengleton obj1 = new ChildSengleton();
Child2Sengleton obj2 = new Child2Sengleton();
obj1.PrintCount();
obj2.PrintCount();
}
}
class Use
{
public static int count = 1;
public Use()
{
count++;
}
public int Count
{
get { return count; }
}
}
public class Singleton
{
private static Singleton instance = new Singleton(1);
private Use useobj;
protected Singleton()
{
}
private Singleton(int count)
{
useobj = new Use();
}
public static Singleton BaseRef
{
get
{
return instance;
}
}
public int Count
{
get
{
return instance.useobj.Count;
}
}
}
public class ChildSengleton : Singleton
{
public void PrintCount()
{
Console.WriteLine(this.Count);
}
}
public class Child2Sengleton : Singleton
{
public void PrintCount()
{
Console.WriteLine(this.Count);
}
}