Thursday, June 26, 2008

Testing Concurrency using ThreadPool (Multithread)

There are times when we need to test our code in concurrent manner where there are some numbers of instances running simultaneously.

Concurrency

This is different with the invocation such as below code where the method will be executed in sequential manner, this kind of test may be useful to test how long it may take to execute the method.

for (int iTest = 0; iTest < 100; iTest++)
{
    TestingMethodA();
}

 

For this testing concurrency, I’m using Joseph Albahari’s Threading in C# articles in ThreadPooling section as references to the MultiThreadRunner class that I created.

Code below in plain English : Submit 5 invocations of TestingMethodA with 10 maximum concurrent threads.

MultiThreadRunner runner = new MultiThreadRunner();           
runner.Run(new MultiThreadRunner.ParameterlessMethodDelegate(TestingMethodA), 5, 10);

 

The MultiThreadRunner class :

class MultiThreadRunner
{
    static object workerLocker = new object();
    static int runningWorkers = 0;

    /// <summary>
    /// The delegate is to be used as a placeholder for a parameterless method to invoke
    /// </summary>
    public delegate void ParameterlessMethodDelegate();
    /// <summary>
    /// An overload to Run method, set the concurrentNoOfInstances to a default no
    /// </summary>
    /// <param name="myMethod">The method to be invoke, passed as a delegate</param>
    /// <param name="noOfInvocations">Total no of invocations to execute</param>
    public void Run(Delegate myMethod, int noOfInvocations)
    {
        this.Run(myMethod, noOfInvocations, 0);
    }
    /// <summary>
    /// The method will submit the method into the ThreadPool
    /// </summary>
    /// <param name="myMethod">The method to be invoke, passed as a delegate</param>
    /// <param name="noOfInvocations">Total no of invocations to execute</param>
    /// <param name="concurrentNoOfInstances">Concurrent no of instances -> ThreadPool.MinThreads</param>
    public void Run(Delegate myMethod, int noOfInvocations, int concurrentNoOfInstances)
    {
        int iRow = runningWorkers = noOfInvocations;
        int iStartWorker, iEndWorker, iCompletion;

        // Adjust the min threads
        SetMinThreads(concurrentNoOfInstances);
        ThreadPool.GetAvailableThreads(out iStartWorker, out iCompletion);
        Debug.WriteLine(string.Format("Available Threads, Start : {0}", iStartWorker));

        for (int i = 1; i <= iRow; i++)
        {
            ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(InvokeMethod), myMethod);
            Debug.WriteLine("Submitted a queue : " + i.ToString());
        }

        lock (workerLocker)
        {
            while (runningWorkers > 0) Monitor.Wait(workerLocker);
        }

        ThreadPool.GetAvailableThreads(out iEndWorker, out iCompletion);
        Debug.WriteLine(string.Format("All threads have been completed, Start : {0} - End : {1} - Completion : {2}", iStartWorker, iEndWorker, iCompletion));
    }

    /// <summary>
    /// Set the ThreadPool Mininum Threads, this is to avoid a delay bottleneck, please refer to
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx
    /// </summary>
    /// <param name="concurrentNoOfInstances"></param>
    private void SetMinThreads(int concurrentNoOfInstances)
    {
        int iMaxWorker, iMinWorker, iCompletion;

        ThreadPool.GetMaxThreads(out iMaxWorker, out iCompletion);
        ThreadPool.GetMinThreads(out iMinWorker, out iCompletion);

        if (concurrentNoOfInstances != 0)
        {
            if (concurrentNoOfInstances > iMaxWorker)
            {
                ThreadPool.SetMinThreads(iMaxWorker, iCompletion);
                Debug.WriteLine("The requested concurrent no of instances is higher than max threads, set the min threads as max threads : " + iMaxWorker);
            }
            else
            {
                ThreadPool.SetMinThreads(concurrentNoOfInstances, iCompletion);
                Debug.WriteLine("Set the min threads to " + concurrentNoOfInstances);
            }
        }
        else
        {
            Debug.WriteLine("Using the default min threads : " + iMinWorker);
        }
    }
    /// <summary>
    /// To invoke the method
    /// </summary>
    /// <param name="myMethod"></param>
    private void InvokeMethod(object myMethod)
    {
        Debug.WriteLine("Invoke the method in thread : " + Thread.CurrentThread.ManagedThreadId);
        ((Delegate)myMethod).DynamicInvoke(null);
        lock (workerLocker)
        {
            runningWorkers--; Monitor.Pulse(workerLocker);
        }
    }
}

or get the complete project from here :

 

Hope this helps with your test as well :D

Wednesday, June 25, 2008

Passing method using delegate

I was doing some code refactoring today and this is one of the things that fits nicely to remove those repetitive codes.

I have lines of code below as an example where I process some data based on certain key.

private void ProcessData()
{
    string theKey;
    Key key = new Key("A", "B");           

    theKey = key.KeyA;
    Console.WriteLine("Processing data with key : {0}", theKey);

    theKey = key.KeyB;
    Console.WriteLine("Processing data with key : {0}", theKey);

    theKey = key.KeyA + key.KeyB;
    Console.WriteLine("Processing data with key : {0}", theKey);
}

This looks simple enough, but imagine what would happen if i replace “the processing data with key…” line with 20 real codes, they suddenly become 60 lines which are repetitive, doing the same thing using the key ;)

 

So this is what I came out with, create a delegate which receives Key object then create 3 new methods which have the same signature as the delegate and will have the logic to construct the key.

private delegate string AssignKeyDelegate(Key key);
private string AssignKeyA(Key key)
{
    return key.KeyA;
}
private string AssignKeyB(Key key)
{
    return key.KeyB;
}
private string AssignKeyAB(Key key)
{
    return key.KeyA + key.KeyB;
}

 

By using this, I can process the data and construct the key based on the appropriate method which is specified in the parameter using the delegate.

private void Run()
{
    ProcessData(new AssignKeyDelegate(AssignKeyA));
    ProcessData(new AssignKeyDelegate(AssignKeyB));
    ProcessData(new AssignKeyDelegate(AssignKeyAB));
}
private void ProcessData(AssignKeyDelegate del)
{
    Key key = new Key("A", "B");           
    string theKey = del(key);
    Console.WriteLine("Processing data with key : {0}", theKey);
}

 

I provided the sample code above as a basic example only, there are many solutions that may come out with this kind of code :) The purpose is only to describe another feature that we can do with delegate.

Hope this helps :)

Asynchronous Delegate in Serviced Component COM+

I’m currently assigned to optimize a COM+ performance which is storing some data in the cache. The loading time will take around 2-3 minutes.

Since it is loading data from different tables and they are not related one with another, I’m thinking of using Asynchronous Delegate for the loading process so they can be loaded in separate threads.

This is what we should get if we use delegates

Async Normal

Load Data A, Load Data B, and Load Data C are executed using delegates :

LoadDataDelegate loadDataA = new LoadDataDelegate(LoadDataA);
IAsyncResult result1 = loadDataA.BeginInvoke(null, null);

LoadDataDelegate loadDataB = new LoadDataDelegate(LoadDataB);
IAsyncResult result2 = loadDataB.BeginInvoke(null, null);

LoadDataDelegate loadDataC = new LoadDataDelegate(LoadDataC);
IAsyncResult result3 = loadDataC.BeginInvoke(null, null);

// Wait the results to complete
loadDataA.EndInvoke(result1);
loadDataB.EndInvoke(result2);
loadDataC.EndInvoke(result3);
  

 

Turned out after I deployed the component to COM+, all the delegates ran in only single thread as sequentially / synchronously.

Only if I create a new thread explicitly, it will create a new thread.

Async COM  

Load Data A is being executed in a new thread, Load Data B, and Load Data C are executed using delegates but they were executed in the same thread synchronously.

Thread loadDataA = new Thread(new ThreadStart(LoadDataA));
loadDataA.Start();

LoadDataDelegate loadDataB = new LoadDataDelegate(LoadDataB);
IAsyncResult result2 = loadDataB.BeginInvoke(null, null);

LoadDataDelegate loadDataC = new LoadDataDelegate(LoadDataC);
IAsyncResult result3 = loadDataC.BeginInvoke(null, null);

// Wait the results to complete
loadDataA.Join();
loadDataB.EndInvoke(result2);
loadDataC.EndInvoke(result3);
   

 

I haven’t really found the reason why for COM+ deployment will have this behavior for delegate asynchronous invocation :(

Note: I’m currently not using this asynchronous operation for shared resources reason which requires major changes.

So my dearest readers, please show me the light if you know the reason, thanks ;)

  

Thursday, June 19, 2008

COM+ Catalog Error : Error code 800401E4 - Invalid syntax

COM

Got this weird error yesterday when trying to start up some COM+ applications in my PC where previously they were working just fine.

Got the solution from here.

Tuesday, June 17, 2008

Watch out for that blank space

We have created a receive location with send port group as the subscriber and will send the message output using FILE adapter and FTP adapter.

Send Port Group

So yesterday, I got an email from the engineering site, they said that they were not able to process the file from the FTP drop. 

Then they sent this output to me :

$ cat FILEA.txt
cat: FILEA.txt: No such file or directory

 

But if they used this, the file is actually there :

$ more *
::::::::::::::
FILEA.txt
::::::::::::::
CONTENT FILE A

 

Another test :

$ more FILEA.txt*
CONTENT FILE A

 

So from the test results above, you probably know what’s the cause right? :P

See that in the target file name properties, there is a blank space behind the “txt”.

Target File Name

After removed the blank space, life is good again :D

Thursday, June 12, 2008

BizTalk MsgBoxViewer

While reading a post from One Blog for BizTalk Engineers, I found an interesting tool, BizTalk MsgBoxViewer, built by Jean-Pierre Auconie, which can be used to monitor and generate reports for BizTalk. You can see a little bit of background of the tool at here.

There are 2 user interfaces to use the tool, through GUI or console.

This is a screen capture for the GUI

BizTalk MsgBoxViewer

This is the screen capture for the consoleBizTalk MsgBoxViewer - Console

And here’s the generated report, I would say that I will need some time to chew the whole report out ;p

BizTalk MsgBoxViewer Report

Go and check it out for your self, it’s definitely worth to try, especially with the “limited” information that we can get by using the BizTalk Administration Console or Health and Activity Tracking :P

Microsoft BizTalk Server Performance Optimization Guide

For Biztalkers, you may want to spend a while to read the new Microsoft BizTalk Server Performance Optimization Guide white paper.

I found this while reading a post from Richard Seroter’s blog from my google reader feeds.