Showing posts with label visual studio 2005. Show all posts
Showing posts with label visual studio 2005. Show all posts

Sunday, March 18, 2007

Taking advantage of duo core processor

I have heard for a while that running a multi-thread program on multi core processor is a lot faster than running it on single core one. So, I decided to conduct a mini-experiment to test whether this is true.

C# Console Application, .NET Framework 2.0


Program.cs


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace PerformanceTester
{
class Program
{
private const int NUM = 5000000;

static void Main(string[] args)
{
for (int i = 0; i < 3; i++)
{
DateTime start;
TimeSpan span;

start = DateTime.Now;
SingleThreaded();
span = DateTime.Now.Subtract(start);
Console.WriteLine(
String.Format("\tSingle Threaded : {0} ms",
span.TotalMilliseconds));

start = DateTime.Now;
DoubleThreaded();
span = DateTime.Now.Subtract(start);
Console.WriteLine(
String.Format("\tDouble Threaded : {0} ms",
span.TotalMilliseconds));

}
Console.Read();

}

private static void SingleThreaded()
{
PrimeGenerator generator = new PrimeGenerator();
List<int> results = new List<int>();
generator.AddPrimes(results, 1, NUM);
}

private static void DoubleThreaded()
{
List<int> results = new List<int>();

Thread t1 = new Thread(delegate()
{
PrimeGenerator generator =
new PrimeGenerator();
generator.AddPrimes(results,1,NUM/2);
});

Thread t2 = new Thread(delegate()
{
PrimeGenerator generator =
new PrimeGenerator();
generator.AddPrimes(results,NUM/2+1,NUM);
});

t1.Start(); t2.Start();
t1.Join(); t2.Join();
}
}
}

PrimeGenerator.cs




using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace PerformanceTester
{
class PrimeGenerator
{
private bool IsPrime(int n)
{
if (n <= 1)
return false;
else if (n <= 3)
return true;
else if (n % 2 == 0)
return false;
else
{
int bound = Convert.ToInt32(Math.Ceiling(Math.Sqrt(n)));
for (int i = 3; i <= bound; i++)
{
if (n % i == 0)
return false;
}
return true;
}
}

public void AddPrimes(List<int> list,int lowerBound,int upperBound)
{
for (int number = lowerBound; number < upperBound; number++)
{
if(IsPrime(number))
lock (list)
{
list.Add(number);
}
}
}
}
}
This program will search for all primes between 1 and 5000000 inclusive. It works in two mode, single threaded and double threaded. The search range is divided into two parts in double threaded mode, 1 - 2500000 and 2500001 - 5000000 (we can obviously see that the work load of the second range is bigger than the first one but since this is informal experiment so I did not care about this point :P). The program also record running times for each mode and print them on the screen.

Here are the results:

Running on my IBM R52 - Intel(R) Pentium(R) M 1.60 GHz
(Single core)

Single Threaded : 11687.5 ms
Double Threaded : 12875 ms
Single Threaded : 12812.5 ms
Double Threaded : 12953.125 ms
Single Threaded : 12000 ms
Double Threaded : 11703.125 ms

Running on my mom's IBM R60 - Intel(R) Core(TM)2 CPU 15500 @ 1.66GHz
(Double core)

Single Threaded : 9171.875 ms
Double Threaded : 5625 ms
Single Threaded : 9109.375 ms
Double Threaded : 5625 ms
Single Threaded : 9109.375 ms
Double Threaded : 5609.375 ms

For single core, the running time is practically the same for each mode. While for double core, double threaded mode gives noticeably better running time.

So, to take advantage of new duo core processors nowadays, considers building your program to support multi threaded mode.

Thursday, February 1, 2007

My first simple .NET Framwork 3.0 app

My friends and I had just submitted the project proposals for Imagine Cup 2007: Software Design (You can find more info about Imagine Cup at http://www.imaginecup.com). One of the requirements of the project, only for the first round here in Thailand, is to build the application on the .NET Framework 3.0 which means it's time to start learning WPF, WCF, WF now!

To get started, make sure you have Visual Studio 2005 and these extensions.


First, I created a new project of type Windows Application under .NET Framework 3.0 category. I named it "HelloWPF".

I then designed the form. The Visual Studio's WPF designer is seperated into 2 panes : one for the visual designer and the other for editing raw XAML code. You can click on the "swap" button to swap the XAML pane and visual designer pane too. However, this CTP version of designer is hard to use and is not very impressive.

After that, I tried to add an event handler to the click event of the button. But there is no same old "Events" tab in the property window. Double clicked the button in the designer also not work. It takes me some time to figured out that I has to map event to code in XAML or to map it in the code under the constructor. I choose the latter way. Here is my C# code.



public partial class Window1 : System.Windows.Window
{

public Window1()
{
InitializeComponent();
btnSayHello.Click +=
new RoutedEventHandler(btnSayHello_Click);
}

void btnSayHello_Click(object sender,
RoutedEventArgs e)
{
txtMessage.Text = "WPF : สวัสดี ว่าไง";
}

}


I could finally press the F5 button and this is the result.


Wednesday, December 13, 2006

Handling exceptions in asynchronous web service call in Visual Studio 2005


I had just finish developing my application for ISO (Information System Organization - one of the subject teached at my university). The requirements are to consume 3 of the services available at http://www.programmableweb.com/matrix and the students can develop their applications for any available platforms. I choose to develop my project, MashOpedia, on the .NET Framework 2.0 using Visual C# Express Edition as my IDE.

Consuming web services with Visual Studio is sure an easy job for those services which provide WSDLs. In Visual Studio .NET 2003, any method exposed from a generated proxy classes have their asynchronous versions whose names are "BeginXXX" and "EndXXX" where "XXX" is original method's name. These methods allow the developers to call web services in asynchronous style easily!

However, when you generated a proxy classes with Visual Studio 2005 there are no these "BeginXXX" and "EndXXX" methods anymore. You will find "XXXAsync" method and "XXXCompleted"event instead. These provide an easier way to invoke a web service in asynchronous style. You first call "XXXAsync" and when the call is completed it will raise "XXXCompleted" event.

I had used the "XXXAsync" method to call web serice in my project. But one problem arises. How do I handle those exceptions generated in another thread ?. In Visual Studio .NET 2003 I can wrap the try..catch block over the "EndXXX" method call. Any exception, such as SocketException caused by internet connectivity problem, would be caught by this block.

But in Visual Studio 2005,


void serv_doGoogleSearchCompleted(object sender, doGoogleSearchCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(e.Error.Message);
...
}

I can detect if there is an error occurred in asynchronous call but I could not handle it. When I intentionally unplug my LAN connection. The program stop working and push me back to the IDE with the mysterious "TargetInvocationException" at line "Application.Run(...)". I dont know how should I handle such case. I try wrap the try..catch block around "Application.Run(...)" too. That works but the form instantly close itself after the exception is catched which is not what I want.

One workaround I used to solve this problem is to wrap a synchronous call within the BackgroundWorker. This allows me to call the web service in asynchronous style (The GUI is not freezed) and allows me to handle exceptions raise by the call too.

private void backgroundSearch_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = null;
try
{
GoogleSearchService googleSearch = new GoogleSearchService();
GoogleSearchResult googleRes = googleSearch.doGoogleSearch(ApplicationSettings.GoogleLicenseKey,
txtKeywords.Text, 0, 10, true, "", false, "", "", "");
...
}
catch (Exception ex)
{
e.Result = ex;
}

}

private void backgroundSearch_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result == null)
{
/* Means operation completed successfully */
...
}
else
{
/* Failed */
...
}

If there is more simple way to solve this problem, feel free to tell me :)