Wcf 在客户端上未调用回调

Wcf 在客户端上未调用回调,wcf,Wcf,我有一个自托管服务,它处理客户端通过net.tcp绑定提交的长时间运行的作业。当作业正在运行(在中)时,服务将通过单向回调将状态更新推送到客户端。这很好,但是当我尝试调用另一个回调来通知客户机作业已完成(也是单向的)时,客户机上永远不会接收/调用回调。在此过程中,我没有收到任何例外情况 我的回调合同如下所示: public interface IWorkflowCallback { [OperationContract(IsOneWay = true)] [ApplyShare

我有一个自托管服务,它处理客户端通过net.tcp绑定提交的长时间运行的作业。当作业正在运行(在中)时,服务将通过单向回调将状态更新推送到客户端。这很好,但是当我尝试调用另一个回调来通知客户机作业已完成(也是单向的)时,客户机上永远不会接收/调用回调。在此过程中,我没有收到任何例外情况

我的回调合同如下所示:

public interface IWorkflowCallback
{

    [OperationContract(IsOneWay = true)]
    [ApplySharedTypeResolverAttribute]
    void UpdateStatus(WorkflowJobStatusUpdate StatusUpdate);

    [OperationContract(IsOneWay = true)]
    [ApplySharedTypeResolverAttribute]
    void NotifyJobCompleted(WorkflowJobCompletionNotice Notice);

}
来自调用回调的服务的代码:(不在服务实现本身中,而是直接从服务实现中调用)

公共WorkflowJobTicket AddToQueue(WorkflowJobRequest请求)
{
if(此.workflowEngine.WorkerPoolFull)
{
抛出新的QueueFullException();
}
var user=ServiceUserManager.CurrentUser;
var context=OperationContext.Current;
var workerId=this.workflowEngine.RunWorkflowJob(用户、请求、新对象[]{new DialogServiceExtension(context)});
var workerjob=this.workflowEngine.FindJob(workerId);
var票证=新的WorkflowJobTicket()
{
JobRequestId=Request.JobRequestId,
JobTicketId=workerId
};
用户登记簿(票证);
workerjob.WorkflowJobCompleted+=此.NotifyJobComplete;
workerjob.Status.PropertyChanged+=this.NotifyJobStatusUpdate;
this.notifyQueueChanged();
回程票;
}
受保护的void NotifyJobStatusUpdate(对象发送方,PropertyChangedEventArgs e)
{
var user=ServiceUserManager.GetInstance().GetUserWithTicket((发送方为WorkflowJobStatus.JobId);
动作动作=(回调)=>
{
ICommunicationObject communicationCallback=(ICommunicationObject)回调;
if(communicationCallback.State==CommunicationState.Opened)
{
尝试
{
var updates=(发送方为WorkflowJobStatus).GetUpdates();
callback.UpdateStatus(更新);
}
捕获(例外)
{
communicationCallback.Abort();
}
}
};
用户调用(动作);
}
受保护的void NotifyJobComplete(WorkflowJob作业,事件参数e)
{
var user=ServiceUserManager.GetInstance().GetUserWithTicket(job.JobId);
动作动作=(回调)=>
{
ICommunicationObject communicationCallback=(ICommunicationObject)回调;
if(communicationCallback.State==CommunicationState.Opened)
{
尝试
{
var NOTIONE=新工作流作业完成通知()
{
票证=user.GetTicket(job.JobId),
RuntimeOptions=job.RuntimeOptions
};
回调。NotifyJobCompleted(通知);
}
捕获(例外)
{
communicationCallback.Abort();
}
}
};
用户调用(动作);
}
user.Invoke(action)
方法中,
action
通过
OperationContext.GetCallbackChannel()
传递回调通道的实例

我可以看到调用作业完成通知的任务是由服务执行的,但我没有在客户端收到调用。此外,在发送完成通知后,可以成功调用更新回调,因此通道似乎没有发生故障

知道为什么在这两个实现几乎相同的回调中,只有一个有效吗


提前感谢您的帮助。

删除NotifyJobComplete中的Try Catch,并查看是否出现任何错误。此外,捕获所有异常并不是处理错误的好方法,您在此处执行此操作的方式将吞没所有错误。感谢@Florian的建议,但注释掉这些行没有任何效果。不管怎样,通过追踪,我可以看出我从来没有进入过那个捕捉区。此外,更新和完成通知都使用相同的下划线
OperationContext
实例,因此即使回调通道出现故障(通过我的catch块或框架),完成通知后的更新通知也应该失败,对吗?是,如果通道出现故障,则通知应失败。您是否100%确定引发了workerjob.WorkflowJobCompleted事件?是的,我确定。我能够单步进入事件处理程序和
任务
,因此可以看到代理上正在调用的方法。
public WorkflowJobTicket AddToQueue(WorkflowJobRequest Request)
{
    if (this.workflowEngine.WorkerPoolFull)
    {
        throw new QueueFullException();
    }
    var user = ServiceUserManager.CurrentUser;
    var context = OperationContext.Current;
    var workerId = this.workflowEngine.RunWorkflowJob(user, Request, new Object[]{new DialogServiceExtension(context)});
    var workerjob = this.workflowEngine.FindJob(workerId);
    var ticket = new WorkflowJobTicket()
    {
        JobRequestId = Request.JobRequestId,
        JobTicketId = workerId
    };
    user.RegisterTicket<IWorkflowCallback>(ticket);
    workerjob.WorkflowJobCompleted += this.NotifyJobComplete;
    workerjob.Status.PropertyChanged += this.NotifyJobStatusUpdate;
    this.notifyQueueChanged();
    return ticket;
}
protected void NotifyJobStatusUpdate(object sender, PropertyChangedEventArgs e)
{
    var user = ServiceUserManager.GetInstance().GetUserWithTicket((sender as WorkflowJobStatus).JobId);
    Action<IWorkflowCallback> action = (callback) =>
    {
        ICommunicationObject communicationCallback = (ICommunicationObject)callback;
        if (communicationCallback.State == CommunicationState.Opened)
        {
            try
            {
                var updates = (sender as WorkflowJobStatus).GetUpdates();
                callback.UpdateStatus(updates);
            }
            catch (Exception)
            {
                communicationCallback.Abort();
            }
        }
    };
    user.Invoke<IWorkflowCallback>(action);
}
protected void NotifyJobComplete(WorkflowJob job, EventArgs e)
{
    var user = ServiceUserManager.GetInstance().GetUserWithTicket(job.JobId);
    Action<IWorkflowCallback> action = (callback) =>
    {
        ICommunicationObject communicationCallback = (ICommunicationObject)callback;
        if (communicationCallback.State == CommunicationState.Opened)
        {
            try
            {
                var notice = new WorkflowJobCompletionNotice()
                {
                    Ticket = user.GetTicket(job.JobId),
                    RuntimeOptions = job.RuntimeOptions
                };
                callback.NotifyJobCompleted(notice);
            }
            catch (Exception)
            {
                communicationCallback.Abort();
            }
        }
    };
    user.Invoke<IWorkflowCallback>(action);
}