4

This is my WCF service. I want to notify multiple subscribers of some updates and do it asynchronously. How do I do that?

// Callback contract
public interface IMyServiceCallback
{
    [OperationContract]
    void Notify(String sData);      
}

public class MyService:IMyService
{
    List<IMyServiceCallback> _subscribers = new List<IMyServiceCallback>();

    // This function is used to subscribe to service.
    public bool Subscribe()
    {
       try
       {
          IMyServiceCallback callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();
        if (!_subscribers.Contains(callback))
            _subscribers.Add(callback);
        return true;
    }
    catch
    {
        return false;
    }
}

// this function is used to notify all the subsribers 
// I want ForEach to be asynchronous. 
public void OnGetMsg(string sData)
{
    _subscribers.ForEach(
            callback =>
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened)
                {
                    callback.Notify(sData); //THIS OPERATION
                }
                else
                {
                    _subscribers.Remove(callback);
                }
            });
   }
}
Pratik Deoghare
  • 35,497
  • 30
  • 100
  • 146
  • Also, am I the only one who thinks WCF is pain in the neck? (You know what I mean by neck.) – Pratik Deoghare Apr 25 '11 at 08:33
  • Where is your problem in the code? Exception or logic (algo) problem? – Peyton Crow Apr 25 '11 at 08:47
  • If one of the subscribers is dead then there is Timeout Exception at `callback.Notify()`. Because of this notification to other subscribers is delayed. – Pratik Deoghare Apr 25 '11 at 08:50
  • If you dont handle that TimeoutException inside that method, the ForEach will break, something like waiting for the other process to complete. Are you handling the exception inside the callback.Notify method()? – Peyton Crow Apr 25 '11 at 09:03
  • I can handle that `TimeoutException` but it won't prevent the delayed notification to other subscribers. – Pratik Deoghare Apr 25 '11 at 09:08
  • Have you limit your connection timeout? How many seconds will that cause a delay if you have 3 seconds connection timeout? When you handle the exception, does the code still crashed? – Peyton Crow Apr 25 '11 at 09:27

1 Answers1

1

You can put it to the thread pool:

 ThreadPool.QueueUserWorkItem(o => callback.Notify(sData));

Just be aware that it might clog up your threadpool when you have many bad subscribers. You probably want to catch exceptions and remove the callback when it failed.

Update: If you don't want to use the .NET thread pool then you can either roll your own or for example use the SmartThreadPool

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
  • That is not a good idea because you will most probably consume threads which are supposed to be used by WCF engine to process incomming requests. – Ladislav Mrnka Apr 25 '11 at 10:56