Click here to Skip to main content
15,883,705 members
Articles / Programming Languages / C#

WCF for Single Instance

Rate me:
Please Sign up or sign in to vote.
3.29/5 (3 votes)
6 Nov 2009CPOL2 min read 37.6K   519   7   5
How WCF can be used to create a single instance of an application

Introduction

Some applications would like to have single instance running at any time.      

To create a single instance application, there are two requirements to be matched:

  1. Application should able to identify if instances of itself are already running.
  2. If so, notify the first instance and let the first instance handle the situation instead.

As the two instances are two different processes altogether, it involves inter process communication. WCF is one of the simpler approaches among many (like using WindowsFormsApplicationBase, IPC and remoting) to solve this problem.

Using the Code

The sample application contains two windows. One is a start up form that launches employee details entry form through which employee details can be saved to XML file.

The requirement is that the application shall open employee details form each time it is run. For the first time, it usually opens up the form.

When another instance is invoked, the first instance will be informed of the second instance, and prompts the user whether to close the form as shown in the below figure:

Image 1

Based on user response, it either closes old form or opens a new employee details form (notice encircled form title in the below figure).

Thus each time the application is run; only one form will be opened.

Image 2

Now let’s look into the code…

Define an interface through which client (another instance) can communicate with server (first instance).

Decorate the interface as “ServiceContract” to expose it to client.

Methods that are decorated as “ OperationContract” alone will be visible to client.

Through Signal() method, the client communicates to the server.

C#
[ServiceContract]
public interface  IServiceContract
{
    /// <summary>
    /// Signals this instance.
    /// </summary>
    [OperationContract]
    void Signal();        
} 	

Service” Class implements the above contract.

Notice InstanceContextMode is set to Single. This is required if a service instance is passed to service host.

C#
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service : IServiceContract
{
    public EmployeeDetailsWindow window;
    private static int formNumber;
    
    void IServiceContract.Signal()
    {
        string strText = "Other instance is selected.\n";
        strText =strText +"Do you want to close this and open the other ?";
        MessageBoxResult result = 
            MessageBox.Show(strText, "Close", MessageBoxButton.YesNo);
        bool blnInstanceClosed = 
            result == MessageBoxResult.Yes ? true : false;
        if (blnInstanceClosed)
        {
            CloseEmployeeWindow();
            Run();
        }
        else
        {
            if (window != null)
                window.Activate();
        }
    }
}

InstanceMutex class has two functions “IsInstanceRunning” and “St<code>artService”.

When “IsInstanceRunning” requests for a channel, if it does not exist “EndPointNotFoundException” is thrown.

Which means this is the first instance. And it has to become the server by calling “StartService”.

StartService” creates service host and opens it to serve the requests.

C#
public class InstanceMutex
{
    public static ServiceHost host;
    
    public static bool IsInstanceRunning(string channelUri)
    {
        ChannelFactory<IServiceContract> factory = 
          new ChannelFactory<IServiceContract>
              (new NetNamedPipeBinding(), new EndpointAddress(channelUri));
        IServiceContract proxy = factory.CreateChannel();
        
        try
        {
            // wait for server to respond
            if (host != null && host.State == CommunicationState.Opened)
            {
                (factory as IContextChannel).OperationTimeout = new TimeSpan(1000);
            }
            //signal server that a new instance is selected
            proxy.Signal();
            return true;
        }
        catch (EndpointNotFoundException e)
        {
            //return false to indicate this instance is first instance
            return false;
        }
    }
   
    public static void StartService(IServiceContract instance, string channelUri)
    {
        host = new ServiceHost(instance, new Uri(channelUri));
        try
        {
          host.AddServiceEndpoint
          (typeof(IServiceContract), new NetNamedPipeBinding(), new Uri(channelUri));
          host.Open();
          (instance as Service).LaucnhStartUpWindow();
        }
        catch (CommunicationException ex)
        {
            host.Abort();
        }
    }
}

Now if another instance is selected, “IsInstanceRunning” gets channel to end point and signals the first instance. And then the first instance does the necessary actions.

After signaling, the second instance shuts down. Hence always a single instance of the application exists.

History

  • 6th November, 2009: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
hishyam16-Mar-11 2:03
hishyam16-Mar-11 2:03 
QuestionWhy do this? Pin
gaurav_verma_mca6-Nov-09 4:42
gaurav_verma_mca6-Nov-09 4:42 
AnswerRe: Why do this? Pin
KN.Sudha6-Nov-09 15:24
KN.Sudha6-Nov-09 15:24 
GeneralRe: Why do this? Pin
gaurav_verma_mca6-Nov-09 18:12
gaurav_verma_mca6-Nov-09 18:12 
GeneralRe: Why do this? Pin
KN.Sudha9-Nov-09 2:37
KN.Sudha9-Nov-09 2:37 
If Singleton is used ,you can just have single instance of application.
If you take example of mutex,it serves this purpose by stopping another process from creating a mutex with same name.
If there is a data that needs to be passed from second instance to first instance(eg:command line arguments)mutex cannot be used.It is possible by WCF.If you extend sample application to accept commandline arguments for "signal" function,and pass these arguments of second to first.
Then first instance handles them.
By WCF,you can not only have single instance ,but communciation,carrying data between processes is also possible.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.