Creating a Multi-Threaded Managed SIP Application

Creating a Multi-Threaded SIP Application

For performance and efficiency, Microsoft Lync Server 2010 events can be handled with worker threads taken from the .NET Framework thread pool.

The simplest approach is to use the .NET Framework thread pool and queue each event from the server (such as a call from Dispatch) as a user work item. In the code sample below, the server signals an event with the wait handle provided by ServerAgent.WaitHandle. When the event is signaled, the application attempts to create a worker thread from the thread pool, which is used to service the event. The event callback method passed to the thread is the ServerAgent.ProcessEvent method, which removes the event (the dispatch) from the server queue and processes it (passes the SIP message to the method specified in the MSPL call to Dispatch).

The code sample below demonstrates the basic structure for threading dispatches from the server. It can be called directly from the Main() (entry point) method of your application, taking an instance of ServerAgent as a parameter.

public void LCServerEventHandler(ServerAgent sa)
{
   ManualResetEvent autoResetEvent = new ManualResetEvent(false);
   WaitHandle[] handleArray = new WaitHandle[] {
                                 myAppServerAgent.WaitHandle,
                                 manualResetEvent
                              };

   WaitCallback waitCallback = new WaitCallback(myAppServerAgent.ProcessEvent);

   while (true)
   {
      int signaledEvent = WaitHandle.WaitAny(handleArray);

      if (signaledEvent == 0)  // The server event wait handle (index = 0) in handleArray was signaled
      {

          // Schedule a worker thread to process the server event
          try
          {
             if (!ThreadPool.QueueUserWorkItem(waitCallBack))
             {
                 Console.WriteLine("QueueUserWorkItem fails, quitting.");
                 return;
             }

          }
          catch (Exception e)
          {
             Console.WriteLine("Unexpected exception: {0}\n{1}",
                               e.Message,
                               e.StackTrace);
          }
       }
       else // Manual reset event handle (index = 1) in handle array was signaled
       {
          Console.WriteLine("Quit handle signaled, worker will quit now\n");
          break;
       }
   }
}