所以我有一个对象引发事件和在Windows服务中托管的WCF服务。
引发的事件当前在Windows服务中的一个类中,WCF服务订阅这些事件,当事件触发时,它们意味着回调客户端,让客户端知道发生在其他部分的事情。 Windows服务。
问题在于回调有时会起作用,有时却不起作用。我检查是否有任何客户回电,如果不是我不打扰。我不确定实现这个的最佳方法是因为有时候:
call = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>();
在异常输出或其设置为null的其他时间获取回调,因为进入WCF服务的事件来自Windows服务的另一部分(A类),而不是来自OperationContext。
简而言之 如何在我的Windows服务的另一部分中发生事件时,如何设置我的WCF服务以提醒客户端?
(更多代码)
在发布活动之前,我会像这样进行检查(只有在我们有客户时才发布):
private void Publish(EoDEvent eodListEvent, EoDItem item)
{
if ( _EoDEventSubscribers == null || _EoDEventSubscribers.Count == 0)
{
//Cannot publish because we have no one listening
return;
}
.....
然后我就这样发布了它:
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);
答案 0 :(得分:0)
所以我发现以下内容只是为了获取回调并在我的foreach循环中触发对客户端的更新。
首先,我正在设置对最新订阅者的呼叫
public void Subscribe()
{
IRiskEoDWCFEvents callback = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>();
call = callback;
lock (_SubscriberLock)
{
if (!_EoDEventSubscribers.Contains(callback))
{
Logging.WriteLine("Adding callback {0}", callback.GetHashCode());
_EoDEventSubscribers.Add(callback);
}
}
}
然后在发布方法上我正在快速检查尝试将其设置为当前回调通道,但如果失败只是抓住我知道的那个:
if ( _EoDEventSubscribers == null || _EoDEventSubscribers.Count == 0)
{
//Cannot publish because we have no one listening
return;
}
if (call == null)
{
try
{
call = OperationContext.Current.GetCallbackChannel<IRiskEoDWCFEvents>();
}
catch
{
call = _EoDEventSubscribers[0];
}
}
虽然这是有效的,但我不确定这是否是最好的方法。