Wednesday, July 27, 2011

What is Parallel keyword and how it works in c# 4

in this sample i am going to discuss what Parallel.ForEach will do...

Here i am creating a list of strings and using parallel foreach making a call to the method which is in server class.

and in our output you can observer the order of the elements. they are not in any particular order...

Because parallel foreach internally create a separate thread for each and every call. which will behave independently.. means each and every request will be handled asynchronously where Normal foreach is Synchronous behavior..

Note:
It is really tough to debug the calls that make in the Parallel.Foreach..

List list = new List();
for (int i = 0; i < 5; i++)
{
list.Add("list item" + i.ToString());
}
Server server = new Server();
Parallel.ForEach(list, (i) => { server.GetDetails(i); });
Console.Read();


public class Server
{
public void GetDetails(dynamic item)
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Request :: " + i + " " + item.ToString());
}
}
}



OutPut
Request :: 0 list item4
Request :: 1 list item4
Request :: 2 list item4
Request :: 0 list item1
Request :: 1 list item1
Request :: 0 list item2
Request :: 1 list item2
Request :: 2 list item2
Request :: 0 list item3
Request :: 1 list item3
Request :: 2 list item3
Request :: 0 list item0
Request :: 1 list item0
Request :: 2 list item0
Request :: 2 list item1

Monday, July 25, 2011

How dynamic in c# 4.0 works

In this Post i will try to give an idea what "dynamic" keyword do.

Have a loot at the following Program class, in the constructor of the program class i am calling StartDeveloperWork and StartDynamicWork methods by passing similar objects in the order.



class Program
{

public Program()
{
//Case 1
StartDeveloperWork(new Developer());
StartDeveloperWork(new ASPNetDeveloper());
StartDeveloperWork(new WPFDeveloper());

//Case 2
StartDynamicWork(new Developer());
StartDynamicWork(new ASPNetDeveloper());
StartDynamicWork(new WPFDeveloper());
}

public void StartWork(Developer d)
{
d.Work();
}

public void StartWork(dynamic d)
{
d.Work();
}
}


class WPFDeveloper : Developer
{
public void Work()
{
Console.Write("WPFDeveloper ");
}
}

class ASPNetDeveloper : Developer
{
public void Work()
{
Console.Write("ASPNetDeveloper ");
}
}

class Developer
{
public void Work()
{
Console.Write("Developer ");
}
}


but the out put displayed for startdeveloperwork will be
Developer
Developer
Developer


and out put displayed for StartDynamicWork will be

Developer
ASPNetDeveloper
WPFDeveloper

.. because we in Developer class we have not marked work method as Virtual so when we are calling with base class reference the method in the base calls will be called.

in the StartDeveloperWork method we are using base class reference for calling work method.

coming to StartDynamicWork we are using dynamic keywork means the type of object will be decided at runtime. so method in the passed object will be called.
if the method is not there in the passed object then it will go to base class for the same method. if the method is not there in base class also then it will throw an target invocation exception.

So be care full and make yourself clear when to use and when not to use

WPF: Build Responsive UI (Threading)

I am going to explain how to build responsive user Interface. Implementing threading in WPF.. and this post may help the people who is getting "The calling thread cannot access this object because a different thread owns it" exception

The most frequent problem or situation wpf developers face is Blocked UI.
This solution also works for "calling thread cannot access this object because a different thread owns it" exception.
when we are pooling some data to/from the server wpf UI will get hangs which will question the capability of WPF.

here i will try to explain how to use thread to overcome this.

In the following code i am creating new instance for task factory and starting a new task.
so all the code we pass in the factory will run in the background..

TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
// DO YOUR SERVER CALLS or SOMETHING which you want to run in the background
});


After looking the above the first question comes in mind is Can i update UI from this task or thread.?
and the answer is NO You can't update UI from the background thread.
for updating UI you have to take the control to the Dispatcher thread.
some thing like this.

TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
// DO YOUR SERVER CALLS or SOMETHING which you want to run in the background
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// UI Related stuff
});
});


We learned how to execute a task in background and how to update UI from that thread.

Now let us discuss about how to execute the task and some other code synchronously.

Consider this scenario.
we have to get some data from the server and after that we have play with data.
means our next action is completely dependent on the callback or completion of Task.

in this case we can use task factory ContinueWith method like following

TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
// DO YOUR SERVER CALLS or SOMETHING which you want to run in the background
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// UI Related stuff
});
}).ContinueWith(t =>
{
if (t.IsFaulted)
{
throw t.Exception;
}
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// do some thig after task completion
});
});


Now i am putting all the three scenario in one place with simple example

ObservableCollection images = new ObservableCollection();
TaskFactory tFactory = new TaskFactory();
tFactory.StartNew(() =>
{
for (int i = 0; i < 50; i++)
{
//GET IMAGE Path FROM SERVER
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
// UPDATE PROGRESS BAR IN UI
});

images.Add(("");
}

}).ContinueWith(t =>
{
if (t.IsFaulted)
{
// EXCEPTION IF THREAD IS FAULT
throw t.Exception;
}
System.Windows.Application.Current.Dispatcher.BeginInvoke((Action)delegate()
{
//PROCESS IMAGES AND DISPLAY
});
});


AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);