views:

94

answers:

2

i am writing a program to test WCF service performance in high concurrency circumstance.

On client side, i start many threads to call a WCF service function which returns a long list of data object.

On server side, in that function called by my client, i need to know the number of clients calling the function.

For doing that, i set a counter variable. In the beginning of the function, i add the counter by 1, but how can i decrease it after the funtion has returned the result?

int clientCount=0;
public DataObject[] GetData()
{
     Interlocked.Increment(ref clientCount);
     List<DataObject> result = MockDb.GetData();
     return result.ToArray();
     Interlocked.Decrement(ref clientCount);    //can't run to here...
}

i have seen a way in c++.

Create a new class named counter.

In the constructor of the counter class, increase the variable. And decrease it in the destructor.

In the function, make a counter object so that its constructor will be called. And after the function returns, its destructor will be called.

Like this:

class counter
{
public:
    counter(){++clientCount;  /* not simply like this, need to be atomic*/}
    ~counter(){--clientCount;  /* not simply like this, need to be atomic*/}
};

...
myfunction()
{
    counter c;
    //do something
    return something;
}

In c# i think i can do so with the following codes, but not for sure.

public class Service1 : IService1
{
    static int clientCount = 0;

    private class ClientCounter : IDisposable
    {
        public ClientCounter()
        {
            Interlocked.Increment(ref clientCount);
        }

        public void Dispose()
        {
            Interlocked.Decrement(ref clientCount);
        }
    }

    public DataObject[] GetData()
    {
        using (ClientCounter counter = new ClientCounter())
        {
            List<DataObject> result = MockDb.GetData();
            return result.ToArray();
        }
    }
}

i write a counter class implement the IDisposable interface. And put my function codes into a using block. But it seems that it doesn't work so good. No matter how many threads i start, the clientCount variable is far less than the threads number.

Any advise would be appreciated.

+2  A: 

Have a look at the various layers WCF uses. You can plug into one of them.

For example add a IDispatchMessageInspector to your EndpointBehavior:

public class ConsoleOutputMessageInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
         Console.WriteLine("Starting call");
         // count++ here
         return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        // count-- here
        Console.WriteLine("Returning");
    }
}

See more here: http://weblogs.asp.net/paolopia/archive/2007/08/23/writing-a-wcf-message-inspector.aspx

Have a look how to extend WCF here: http://msdn.microsoft.com/en-us/magazine/cc163302.aspx#S6

Flo
thanks, i'll try it.
ZhengZhiren
A: 

Have you tried WCF's built-in performance counters:

http://msdn.microsoft.com/en-us/library/ms735098.aspx

Scott