So I have an object that raises events and a WCF Service hosted within a windows service.
The raised events are currently in a class within the Windows service and the WCF Service subscribes to those events and when the events fire they are meant to be a callback to the client to let the client know something happened on another part of the Windows Service.
The issues is that at times the callbacks work and at times they do not. I have checks to see if there are any clients to call back to if not I don't bother. I am not sure the best way to implement this is because at times the:
call = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>();
Gets a callback at other times it exceptions out or is set to null because the event coming into the WCF service is coming from another part of the Windows Service (A class) rather than from the OperationContext.
In Short How can I setup my WCF service to alert clients when events occurred in another part of my windows service?
(More Code)
Before publishing out the events I do a check like so (Only care to publish when we have clients):
private void Publish(EoDEvent eodListEvent, EoDItem item)
{
if ( _EoDEventSubscribers == null || _EoDEventSubscribers.Count == 0)
{
//Cannot publish because we have no one listening
return;
}
.....
Then I publish it all out like so:
Thread myThread = new Thread(myObject =>
{
lock (_SubscriberLock)
{
foreach (IRiskEoDWCFEvents callback in _EoDEventSubscribers)
{
if (callback.GetHashCode() != myObject.GetHashCode())
{
Logging.WriteLine("Sending event to {0}", callback.GetHashCode());
try
{
if (eodListEvent == EoDEvent.EoDComponentStarted)
callback.EoDComponentStarted(item);
else if (eodListEvent == EoDEvent.EoDComponentCompleted)
callback.EoDComponentCompleted(item);
.....
}
catch (Exception ex)
{
FaultException faultex = ex as FaultException;
if (faultex == null)
{
Logging.WriteLine("Callback failed, removing {0}", callback.GetHashCode());
toRemove.Add(callback);
}
}
}
}
if (toRemove.Count > 0)
{
foreach (IRiskEoDWCFEvents cb in toRemove)
{
_EoDEventSubscribers.Remove(cb);
}
}
}
});
myThread.Priority = ThreadPriority.Highest;
myThread.Start(call);
So I find that the following is working just to get a callback and to fire off updates to clients in my foreach loop.
First I am setting call to the latest subscriber
Then further on the publish method I am doing a quick check trying to set it to the current call back channel but if that fails just grab one that I know is there:
Although this is works I am not sure if this is the best way to do this.