Menus

Sunday, January 27, 2013

Three ways to do WCF instance management

Introduction

Very often we would like to control the way WCF service objects are instantiated on a WCF server. You would want to control how long the WCF instances should be residing on the server.
The WCF framework has provided three ways by which we can control WCF instance creation. In this article, we will first try to understand those three ways of WCF service instance control with simple code samples of how to achieve them. Finally, we will compare when to use them and under what situations.

WCF service object instancing basics

In normal WCF request and response communication, the following sequence of actions takes place:
  • WCF client makes a request to a WCF service object.
  • WCF service object is instantiated.
  • WCF service instance serves the request and sends the response to the WCF client.
Following is a pictorial representation of how WCF requests and responses work.

Following are different ways by which you can create WCF instances:
  • Create a new WCF service instance on every WCF client method call.
  • Only one WCF service instance should be created for every WCF client session.
  • Only one global WCF service instance should be created for all WCF clients.
To meet the above scenarios, WCF has provided three ways by which you can control WCF service instances:
  • Per call
  • Per session
  • Single instance

Per call instance mode

When we configure a WCF service as per call, new service instances are created for every method call you make via a WCF proxy client. The image below shows this in a pictorial format:
  • The WCF client makes the first method call (method call 1).
  • A new WCF service instance is created on the server for this method call.
  • The WCF service serves the request and sends the response and the WCF instance is destroyed and given to the garbage collector for clean up.
  • Now let’s say the WCF client makes a second method call, a new instance is created, the request is served, and the WCF instance is destroyed.
In other words, for every WCF client method call, a WCF service instance is created, and destroyed once the request is served.

How to implement WCF per call instancing

In order to specify the instancing mode, we need to provide the InstanceContextMode value in the ServiceBehavior attribute as shown below. This attribute needs to specified on the Service class. In the below code snippet, we have specified intCounter as a class level variable and the class counter is incremented by one when the Increment method is called.
 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Percall)] 
public class Service : IService
{
    private int intCounter;

    public int Increment()
    {
        intCounter++
        return intCounter;
    }
}

At the client, we consume the WCF client and we call the Increment method twice.
ServiceReference1.ServiceClient obj = new ServiceReference1.ServiceClient(); 
MessageBox.Show(obj.Increment().ToString());
MessageBox.Show(obj.Increment().ToString());
Even though we have called the Increment method twice, we get the value ‘1’. In other words, the WCF service instance is created for every method call made to the WCF service instance so the value will always be one.

Per session instance mode

Very often we need to maintain state between method calls or for a particular session. For those kinds of scenarios, we will need to configure the service per session. In per session, only one instance of a WCF service object is created for a session interaction. The figure below explains this in pictorial format.
  • The client creates the proxy of the WCF service and makes method calls.
  • A WCF service instance is created which serves the method response.
  • The client makes one more method call in the same session.
  • The same WCF service instance serves the method call.
  • When the client finishes its activity, the WCF instance is destroyed and served to the garbage collector for clean up.

How to implement per session instancing

To configure service as per session, we need to configure the ServiceBehavior attribute with a PerSession value in the InstanceContextMode object.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
public class Service : IService
{
    private int intCounter;
    public int Increment()
    {
        intCounter++
        return intCounter;
    }
}
At the client side, when we run the below client code, you should see the value ‘2’ after the final client code is executed. We have called the method twice so the value will be seen as two.
 
ServiceReference1.ServiceClient obj = new ServiceReference1.ServiceClient(); 
MessageBox.Show(obj.Increment().ToString());
MessageBox.Show(obj.Increment().ToString());

Single instance mode

Often we would like to create one global WCF instance for all WCF clients. To create a single instance of a WCF service, we need to configure the WCF service as Single instance mode. Below is a simple pictorial notation of how the single instance mode will operate:
  • WCF client 1 requests a method call on the WCF service.
  • A WCF service instance is created and the request is served. The WCF service instance is not destroyed, the service instance is persisted to server other requests.
  • Now let’s say some other WCF client, e.g., client 2, requests a method call.
  • The same WCF instance which was created by WCF client 1 is used to serve the request for WCF client 2. In other words, only one global WCF server service instance is created to serve all client requests.

How to implement single instance mode

In order to create a single instance of a WCF service, we need to specify InstanceContextMode as Single.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class Service : IService
{
}
 
If you call the WCF service from a different client, you will see the counter incrementing. The counter becomes a global variable.

When should you use per call, per session, and single mode?

Per call

  • You want a stateless services.
  • Your service holds intensive resources like connection objects and huge memory objects.
  • Scalability is a prime requirement. You would like to have a scaled out architecture.
  • Your WCF functions are called in a single threaded model.

Per session

  • You want to maintain states between WCF calls.
  • You a scaled up architecture.
  • Light resource references.

Single

  • You want share global data through your WCF service.
  • Scalability is not a concern.

WCF Concurrency (Single, Multiple, and Reentrant) and Throttling

Introduction and goal

In this article, we will concentrate on WCF concurrency and throttling. We will first try to understand what is WCF concurrency and the three important types of WCF concurrency. We will then see a small sample of WCF concurrency with Single and Multiple. We will then go through 9 combinations of WCF concurrency and instancing. Finally we will try to understand how to configure throttling using the WCFweb.config’ file.

Why do we need concurrency in WCF?

If you search on the web for the dictionary meaning of concurrency, you will find the following definition:
Happening at the same time
WCF concurrency helps us configure how WCF service instances can serve multiple requests at the same time. You will need WCF concurrency for the below prime reasons; there can be other reasons as well but these stand out as important reasons:
  • Increase throughput: Many times you want to increase the amount of work your WCF service instance does at any moment of time. In other words, you would like to increase the throughput. Throughput means how much work a given thing can do.
  • By default, a WCF service handles only one request at a given moment of time.
  • Integration with a legacy system: Many times your WCF services interact with legacy systems like VB6, COM, etc. It’s very much possible that these systems are not multithreaded, in other words they handle only one request at any given time. So even though your WCF service has concurrent capabilities, you would still like to handle one request at a time. This is achieved by using throttling in combination with WCF concurrency capabilities.

WCF concurrency and instancing – Two different things

WCF instancing and WCF concurrency are two different things. WCF instance dictates how objects are created while WCF concurrency dictates how many requests can be handled by WCF objects.
I do understand that many of our developer friends know this difference, but as you go deeper into WCF concurrency, there is lot of connection with WCF instancing also, so I wanted to just emphasize the differences.
WCF instancing gives three levels of WCF object instance controls: per call, per session, and single. In similar lines, WCF also has three ways of implementing WCF concurrency.

Three types of WCF concurrency

There are three ways by which you can handle concurrency in WCF: single, multiple, and reentrant. To specify WCF concurrency, we need to use the ServiceBehavior tag as shown below, with the appropriate ‘ConCurrencyMode’ property value.

Single: A single request has access to the WCF service object at a given moment of time. So only one request will be processed at any given moment of time. The other requests have to wait until the request processed by the WCF service is completed.
Multiple: In this scenario, multiple requests can be handled by the WCF service object at any given moment of time. In other words, requests are processed at the same time by spawning multiple threads on the WCF server object. So you have great throughput here but you need to ensure concurrency issues related to WCF server objects.
Reentrant: A single request thread has access to the WCF service object, but the thread can exit the WCF service to call another WCF service or can also call a WCF client through callback and reenter without deadlock.

Sample code demonstration

In order to demonstrate this, let’s create a simple sample code as shown below. We will create a simple WCF service with a method name Call. When a client calls this WCF service, it will display the following details:
  • Client name that made the call. This value will be provided as an input when the client wants to make a call to the WCF service.
  • Instance number, this will represent the number of WCF instances which are serving the request.
  • Thread number which is executing the method.
  • Time when the Call method was actually called.
Below is the service contract of the Call method. Please note that OperationContract is defined with IsOneWay as true.

[ServiceContract]
public interface IHelloWorldService
{
    [OperationContract(IsOneWay=true)]
    void Call(string ClientName);
}
 
Below is a simple implementation of the service contract IHelloWorldService interface. It has an instance variable i which helps us maintain the instance counter and a simple Console.Writeline which displays the client name, instance number, thread number, and time when the method was called.
This method waits for 5 seconds using the ‘Thread.Sleep’ function.
 
public class HelloWorldService : IHelloWorldService
{
    // maintain instance count 
    public int i;
    public void Call(string ClientName)
    {
        // increment instance counts
        i++;




        // display client name, instance number , thread number and time when 
        // the method was called




        Console.WriteLine("Client name :" + ClientName + " Instance:" + 
          i.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + 
          " Time:" + DateTime.Now.ToString() + "\n\n");




        // Wait for 5 seconds
        Thread.Sleep(5000);
    }
}
 
This WCF service will be self hosted using WsHttpBinding as shown below. We have chosen 
self hosting so that we can monitor the time, threads, 
and number of instances of the WCF service.
 
static void Main(string[] args)
{
    //Create a URI to serve as the base address
    Uri httpUrl = new Uri("http://localhost:8010/MyService/HelloWorld");




    //Create ServiceHost
    ServiceHost host = new ServiceHost(typeof(ClassLibrary1.HelloWorldService), httpUrl); 




    //Add a service endpoint
    host.AddServiceEndpoint(typeof(ClassLibrary1.IHelloWorldService), new WSHttpBinding(), "");




    //Enable metadata exchange
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    host.Description.Behaviors.Add(smb);




    //Start the Service
    host.Open();




    Console.WriteLine("Service is host at " + DateTime.Now.ToString());
    Console.WriteLine("Host is running... Press <Enter> key to stop");
    Console.ReadLine();
}
 
From the client side, we will make five continuous calls simultaneously on the WCF service.
Below is the code snippet for this:
 
Console.WriteLine("Enter Client name");
string str = Console.ReadLine();
ServiceReference1.HelloWorldServiceClient obj = 
             new ServiceReference1.HelloWorldServiceClient();




for(int i=0;i<5;i++)
{
    obj.Call(str);
}
If you run the above project and monitor your WCF server service, you will see the screenshot. There are two important points to note:
  • By default the WCF service is configured to run with per call. So new instances are created every time the service runs. Instance 1 indicates new instances created for every method call.
  • By default the concurrency is single so the same thread is used to service all five requests which are sent from the WCF client side. You can see the value of the thread is always 4.
  • The most important factor is time. As concurrency is configured as single, it will be called one after another sequentially. You can notice this from the time difference of method calls of 5 seconds.

Let’s go and change the concurrency mode to multiple. In order to change the concurrency mode to multiple, we need to specify Multiple as the concurrency mode as shown in the below code snippet.

If you run the client now, you can see different threads (i.e., thread 4, 5, 6, 7, and 8) are spawned to serve the request and the time of the method calls are almost same. In other words, the methods are executed concurrently on different threads.
In short, you are now having a higher throughput in less amount of time.

9 combinations of Instancing and Concurrency

There are 9 combinations of concurrency and instancing as shown in the below table. In the sections below, we will discuss this in more detail.
InstanceContext
Mode
ConcurrencyMode
Single (Default) Multiple Reentrant
Single
(Single instance for all clients)
Single thread for all clients. Multiple threads for all clients. Single threads for all clients, locks are released when calls diverted to other WCF services.
PerSession (Default)
(Multiple instance per client)
Single thread for every client. Multiple threads for every request. Single threads for all clients, locks are released when calls diverted to other WCF services.
PerCall (Multiple instances for every method call) Single thread for every client. Single thread for every client Single threads for all clients, locks are released when calls diverted to other WCF services.

Instance mode = Per Call and Concurrency = Single

With Per Call, new WCF instances are created for every method call made to the WCF server service. The default concurrency is Single so only one thread will be used to serve all instances.
Below is a simple pictorial representation of what will happen in Per Call and Single concurrency scenarios:
  • For every client instance, a single thread will be allocated.
  • For every method call, a new service instance will be created.
  • A single thread will be used to serve all WCF instances generated from a single client instance.

If you refer the previous sample, you can see how threads are the same and the halt of 5 seconds on the WCF service.

Instance mode = Per Call and Concurrency = Multiple 

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall, 
                 ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HelloWorldService : IHelloWorldService
{
}
 
In this combination, multiple instances are created for every call but multiple threads serve every method call to a WCF service instance. You can see in the below figure we have two WCF service instances and every instance has multiple WCF service objects created for every method call. Every method call is handled by multiple threads.

In the above sample, if you remember, we have multiple threads serving every method call and the time difference between every method call is reduced considerably. The method calls are fired approximately at the same time.

Instance mode = Per Session and Concurrency = Single

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, 
                 ConcurrencyMode = ConcurrencyMode.Single)]
public class HelloWorldService : IHelloWorldService
{
} 

In this combination, one WCF service instance is created for every WCF client session because the WCF instance mode is set to per session. All the method calls are executed in a sequential manner one by one. In other words, only one thread is available for all method calls for a particular service instance.
If you run the sample code with Per Session and Single combination mode, you will find the same thread executes all requests with the same WCF instance per session.

Instance mode = Per Session and Concurrency = Multiple

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, 
                 ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HelloWorldService : IHelloWorldService
{
}
 
Instance mode ‘PerSessionconcurrency is the default setting in WCF
In this combination, one WCF instance is created for every WCF client session and every method call is run over multiple threads. Below is a pictorial representation:

If you run the sample code attached with this article, you will find the same instance with every method call running on different methods.

To get a better idea, you can run different client exe instances with different names as shown below. You will notice how every client gets its own WCF service instance with every method allocated to run on different threads.

Instance mode = Single and Concurrency = Single


[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, 
                 ConcurrencyMode = ConcurrencyMode.Single)]
public class HelloWorldService : IHelloWorldService
{
}
In this combination, only one instance of a WCF service instance is created which serves all requests which are sent from all WCF clients. These requests are served using only one thread.

You can see in the below figure approximately one thread is assigned for every WCF client call and only one instance of the WCF service is created.

Instance mode = Single and Concurrency = Multiple

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, 
                 ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HelloWorldService : IHelloWorldService
{}
In this combination, one WCF service instance is created for serving all WCF clients. All requests are served using multiple / different threads.

You can see from the output that we have 6 threads serving 10 requests, as compared to previously we had approximately only two threads.

Reentrant

In this mode, only one thread runs to serve all requests. If your WCF service makes an outbound call to some other WCF service, or makes a client call, it releases the thread lock. In other words, until the outbound call is completed, other WCF clients can not make calls.

Throttling behavior

WCF throttling helps you to put an upper limit on the number of concurrent calls, WCF instances, and concurrent sessions. WCF provides three ways by which you can define upper limits: MaxConcurrentCalls, MaxConcurrentInstances, and MaxConcurrentSessions.
  • MaxConcurrentCalls: Limits the number of concurrent requests that can be processed by WCF service instances.
  • MaxConcurrentInstances: Limits the number of service instances that can be allocated at a given time. When it’s PerCall services, this value matches the number of concurrent calls. For PerSession services, this value equals the number of active session instances. This setting doesn’t matter for Single instancing mode, because only one instance is ever created.
  • MaxConcurrentSessions: Limits the number of active sessions allowed for the service.
All the above three settings can be defined in the servicebehaviors tag as shown in the below XML snippet:
<serviceBehaviors> 




<behavior name="serviceBehavior"> 




<serviceThrottling maxConcurrentCalls="16"
   maxConcurrentInstances="2147483647" maxConcurrentSessions="10" /> 




</behavior> 




</serviceBehaviors>

Default values for WCF throttling

Below is a simple table which shows the default settings for throttling for different WCF versions:
MaxConcurrentSessions MaxConcurrentSessions MaxConcurrentSessions
WCF 3.0 / 3.5 6 26 10
WCF 4.0 16 * processorcount MaxConcurrentCalls MaxConcurrentCalls
+
MaxConcurrentSessions 100 * processorcount
100 * processorcount

Step by Step SQL Server Profiler in SQL Server 2005

Introduction

Microsoft SQL Server Profiler is a graphical user interface to SQL Trace for monitoring T-SQL Statements of Database Engine. We can save and reuse the state at a later point of time.
  • We can do the following using SQL Server Profiler
    • Create a trace
    • Watch the trace results as the trace runs
    • Store the trace results in a table
    • Start, stop, pause, and modify the trace results as necessary
    • Replay the trace results
  • Use SQL Server Profiler to monitor only the events in which you are interested.
Menu Path: Start | All Programs | Microsoft SQL Server 2005 | Performance Tools | SQL Server Profiler.
The following screen will come:
Screenshot - pic1.jpg
Figure 1.0
Click on <Connect> Button. New Properties Screen will come:
Screenshot - properties.jpg
Figure 1.1
It has two selection tabs:
  • General: It is used for general setting for Trace Database Engine.
  • Event: It is used to add or remove some selected event for monitor.
In General Section (as given in Figure 1.1), it is divided into four sections.
Section 1: In this section, you have to just specify the name of your trace, Trace provider name and server name are predefined and based upon your SQL Server.
And it is not editable.
Section 2: It is the template section. You can choose different type of Templates based upon your requirements. It is the configuration for trace. By default, it is "Standard (Default)" templates. Others templates are T-SQL, T-SQL Duration, T-SQL Reply, T-SQL SPs, etc. You can create your own custom Templates by selecting different Events and Event Class. It is saved as ".tdf" Extension.
Section 3: This section is related to save your trace. Either as File (.trc) or in a database. as table. While clicking on Save to file check box, File save dialog box should open and you can save that file (with .trc extension).
If you check the "Save to Table", it will connect with your server and ask you to which database you want to save that trace table information.
Screenshot - savetotable.jpg
Figure 1.2
Section 4: You can stop your trace on a particular time. Check the "Enable trace stop time" checkbox and give the time at which you want to stop track, SQL Server will automatically stop trace on that time.
Now Move To "Event Section" Tab.
Now we need to know some definition with respect to SQL Server Profiler.

What is an Event?

An Event is an action or operation that is performed in your SQL Server 2005 Database Engine.
Some examples of Events are:
    • Transact-SQL SELECT, INSERT, UPDATE, and DELETE statements.
    • User login and logout
    • Execution of Stored procedures
    • Operation with cursor
SQL Server profiler is able to trace all of these events and all these events are categories on a particular Event class.

What is an Event Class?

Event class is a type of event that can be traced.
Some examples are:
  • SQL: BatchCompleted
  • SQL: Batch Starting
  • Audit Login
  • Audit Logout
  • Lock: Acquired
  • Lock: Released
Now you can select events from this screen:
Screenshot - events.jpg
Figure 1.3
In section 1, we can select the proper check box based upon our requirement, section 2 will display the details of Selected events and Events class. If you check in the check box of section 3, you will get all the list of Events and Columns in Section 1.
Section 4 is something like customization. Just click on the "Column Filter Button". In this section, you can specify some condition (like or Not like).
Screenshot - Filter1.jpg
Figure 1.4
By clicking on "Organize Column" button, you can change the sequence of order of selected events.
Now Click on the "Run" Button, then Trace window will come:
Screenshot - trace1.jpg
Screenshot - trace2.jpg
Figure 1.5
Using these windows, you will get the detailed time duration of a query and all other events information that you have selected.
You can save this result and use it in future. Or you can extract a particular query from the trace, just right click and click on "Extract Event Data". And save this as a SQL Script.

Reply in SQL Server Profiler

SQL Server profiler has a Reply facility which has the ability to save a trace and replay it later.
Replay is useful to troubleshoot an application. Trace replay supports debugging by using Toggle Breakpoint and the Run to Cursor options on the SQL Server Profiler Replay menu.
Anything changed in SQL Server Management Studio will be traced by the SQL Profiler. So it can basically be used for database performance check. We also have "SQL Server Performance Monitor" to monitor the System and Server performance too.

Sunday, January 20, 2013

Handling Empty Data in an ASP.NET Repeater control



The GridView has an EmptyDataText property or the <EmptyDataTemplate> that lets us handle EmptyData. However the Repeater has no such property or template. In this short article, we will see how to adopt a simple technique to handle empty data in an ASP.NET Repeater control without creating a custom control.
Drag and drop a Repeater and a SQLDataSource control to the page. Bind the Repeater to the SQLDataSource as you usually do
<div>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1"            
    onitemdatabound="Repeater1_ItemDataBound">
 <HeaderTemplate>
    <table border="1" cellpadding="3" cellspacing="3">
    <tr bgcolor="blue">
    <td><b>CustomerID</b>
    </td>
    <td><b>CompanyName</b>
    </td>
    <td><b>ContactName</b>
    </td>
    <td><b>ContactTitle</b></td>
    </tr>
</HeaderTemplate>
 <ItemTemplate>
     <tr>
     <td>
        <%#DataBinder.Eval(Container.DataItem, "CustomerID")%>
     </td>
     <td>
        <%#DataBinder.Eval(Container.DataItem, "CompanyName")%>   
     </td>
     <td>
        <%#DataBinder.Eval(Container.DataItem, "ContactName")%>   
     </td>
     <td>
        <%#DataBinder.Eval(Container.DataItem, "ContactTitle")%>   
     </td>
     </tr>
 </ItemTemplate>
 <FooterTemplate>
 </table>           
 </FooterTemplate>

</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
    ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
    SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName],
    [ContactTitle], [Address] FROM [Customers] " >
</asp:SqlDataSource>
</div>
In your web.config, add a connection string as shown below:

      <connectionStrings>
            <add name="NorthwindConnectionString" connectionString="Data Source =(local);Integrated Security = SSPI; Initial Catalog=Northwind;"/>
      </connectionStrings>

If you run the application, the repeater would display the data from the database. Now change the query so that it returns empty data.
SELECT [CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address] FROM [Customers] WHERE CUSTOMERID=’XYZ’

On running the application, you would see the following:
Empty Data
Now this display is not elegant enough to inform the user that there is no data, right? So let us see how to display a message in the Repeater control when there is no data present.
In the <FooterTemplate>, add a Label with some empty data text and set its visible property to false.
<FooterTemplate>
 <tr>
 <td>
 <asp:Label ID="lblEmptyData"
        Text="No Data To Display" runat="server" Visible="false">
 </asp:Label>
 </td>
 </tr>
 </table>           
 </FooterTemplate>
Now add an ItemDataBound event to the Repeater
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1"            
    onitemdatabound="Repeater1_ItemDataBound">
In the code behind, write the following code:
C#
    protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (Repeater1.Items.Count < 1)
        {
            if (e.Item.ItemType == ListItemType.Footer)
            {
                Label lblFooter = (Label)e.Item.FindControl("lblEmptyData");
                lblFooter.Visible = true;
            }
        }
    }
VB.NET
      Protected Sub Repeater1_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
            If Repeater1.Items.Count < 1 Then
                  If e.Item.ItemType = ListItemType.Footer Then
                        Dim lblFooter As Label = CType(e.Item.FindControl("lblEmptyData"), Label)
                        lblFooter.Visible = True
                  End If
            End If
      End Sub
The code checks if the Repeater has items in it. If the items count is less than 1, the code uses the FindControl() to locate the label and set it to visible.
On running the application again, you get to see the message 'No Data To Display' as shown in the screenshot below. This is certainly more user friendly than letting the user wonder why the data was not displayed at the first place.