我的应用程序正在使用带有回调通道的net.tcp WCF服务。出于某种原因,我无法在事件上发送回调。这就是我正在做的事情(所有代码服务器端):
初始化时:
OperationContext Context { get; protected set; }
...
Context = OperationContext.Current;
活动:
var callback = Context.GetCallbackChannel<IServiceCallbackContract>();
callback.SomeMethod();
此问题在SomeMethod()
失败,但出现以下异常:{"Cannot access a disposed object.\r\nObject name: 'System.ServiceModel.Channels.ServiceChannel'."}
答案 0 :(得分:3)
Configure Tracing并查看您的频道出现了什么异常。
答案 1 :(得分:2)
我遇到了类似的问题,我的服务会对业务层进行异步调用,然后等待事件重新启动服务。当事件触发时,Callback上下文丢失。我没有详细研究为什么会这样,但我最终实现了一个解决方法,主要是存储对currentcontext的引用,然后触发一个单独的Thread调用来调用业务层,一旦完成就触发回调我存储的参考文献。
1)创建一个新的类,它包含我的输入请求和回调的反馈,例如。
public struct MyCallbackDetails {
public MyCallbackDetails(IMyServiceCallback callback, RequestType request) : this()
Callback = callback;
Request = request;
}
public IMyServiceCallback Callback { get; set; }
public RequestType request { get; set; }
}
2)然后我将触发传递MyCallbackDetails对象而不仅仅是请求的单独线程:
public ResponseType MyServiceMethod(RequestType request) {
//...Do Some Stuff
//Create MyCallbackDetails object to store reference to the callback and keep channel open
MyCallDetails callDetails = new MyCallDetails(OperationContext.Current.GetCallbackChannel<IMyServiceCallback>(), request);
//Fire off a new thread to call the BL and do some work
Thread processThread = new Thread(RunCallbackMethod);
processThread.Start(callDetails);
}
3)我的RunCallbackMethod将进行BL调用并以回调进行响应。
void RunCallBackMethod(Object requestDetails)
{
//Use callbackdetails to make BL calls
MyCallbackDetails callDetails = (MyCallbackDetails)requestDetails;
// Make BL call - all code under here is syncrhonous
ResponseType response = BusinessLayer.BusinessMethod(callDetails.Request);
//NB: If your responsetype is a business object you will need to convert it to a service object
callDetails.Callback.SomeMethod(results);
}
注意:是的,我现在已经废除了从我的业务层火灾回到服务层的事件,但是因为我正在为业务层启动一个单独的线程,它仍然异步运行并且行为与我是一样直接以ASync方式调用BL并等待事件通知其完成。
PS:感谢Rory的想法和大部分代码来实现这一点。
答案 2 :(得分:0)
您是否尝试直接使用OperationContext.Current而不是实例变量Context?
答案 3 :(得分:0)
此问题已解决为我的错误。回调按设计工作,除了一些是陈旧的,当被调用时抛出异常。由于我没有尝试/捕捉它们,整个事件在那些陈旧的回调中打破:(。
感谢所有试图回答我问题的人。
答案 4 :(得分:0)
我的聊天应用中遇到了类似的问题。如果我关闭了我的应用程序,然后再次尝试打开,那么在打开频道时我会继续Cannot access a disposed object
。
通过应用程序向后追踪我执行了以下操作以找到根本原因。
问题是,如果我错了,WCF专家会纠正我,因为OperationContract就是这样
[OperationContract(IsInitiating = false, IsTerminating = true)]
bool RemoveUser(Client user);
设置IsTerminating = true
意味着在服务处理注销方法之前通道已关闭,因此当它尝试回调时,它无法进行回调。
设置IsTerminating = false
并关闭客户端的频道为我排序问题。
在我的应用程序中,回调不应该发生,但这是一个单独的问题,而不是相关的。重点是,如果您对某个操作有IsTerminating = True
,那么请确保您没有使用回调。