发布
社区首页 >问答首页 >WCF回调实现函数从不调用

WCF回调实现函数从不调用
EN

Stack Overflow用户
提问于 2012-03-29 17:01:06
回答 3查看 3.1K关注 0票数 2

我正在设计一个带有回调的WCF服务,但我的回调函数的实现从未被调用过。我对生成的服务代理感到困惑,所以请帮助我。

场景如下:在服务器端,我定义了服务接口IMyService和回调接口IMyServiceCallback,我还在服务器项目中实现了IMyService。除了服务器项目,我肯定还有另一个客户端项目,我在其中添加了VS中的服务引用。我在客户端实现了IMyServiceCallback接口。所以问题来了:当我调试它的时候,这个函数从来没有进入我的IMyServiceCallback实现,当然也没有得到想要的结果。

这就是我感到困惑的地方:当我在客户端添加服务引用时,它实际上在本地生成了三个接口: IMyService、IMyServiceCallback和IMyServiceChannel以及客户端代理类。在我的本地IMyServiceCallback实现中,我声明该类实现本地IMyServiceCallback接口,而不是来自服务端的接口。这会是问题所在吗?为什么在不同的项目下有两个接口声明(因此有不同的命名空间)?我实现客户端接口的原因是,如果我从服务器端接口实现,当我试图调用服务时,它会给出错误:“提供给ChannelFactory的InstanceContext包含不实现CallbackContractType的UserObject错误”。另一个令人困惑的部分是,在服务器端,如果我将回调接口名称声明为IMyCallback或其他名称,而不是IMyServiceCallback,则在客户端生成的接口仍然是IMyServiceCallback,这是服务接口的名称加上后缀" callback“。在这种情况下,我还得到了“提供给ChannelFactory的InstanceContext包含没有实现CallbackContractType错误的UserObject”。

我想我对“添加服务引用”以及我应该如何实现接口(应该实现哪个接口)有一些误解。有人能帮帮我吗?谢谢!

更新:

我以某种方式解决了这个问题。首先,这两个声明是可取的。本地客户端需要实现本地接口,该接口是在添加服务引用时生成的。我的问题是我也定义了一个DataContract,但是生成的引用文件没有它。这可能是因为我添加了服务项目的程序集作为引用(在本例中有人说添加服务引用不会生成Datacontract),也可能是因为我缺少DataMember属性。但不管怎样,在我修复了这两个部分之后,函数现在可以工作了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-29 18:17:10

当您“添加服务引用”并生成代理时,它与您的服务实现是完全分开的。请记住,您可能正在使用尚未编写的服务,并且无法访问服务源代码。

客户端代码应该使用客户端生成的接口。如果您更改了服务,则需要重新生成代理。

如果您觉得这太混乱了,并且您知道您将始终控制两端,那么您可以共享公共程序集中的服务接口,并在运行时使用DuplexChannelFactory.CreateChannel()生成一个代理类。

至于你的问题,我只能假设你没有正确注册你的回调。这篇文章涵盖了here

票数 2
EN

Stack Overflow用户

发布于 2012-03-29 17:30:01

如果你想发布,你必须在同一个项目中同时实现IMyServiceCallback和IMyService。如果只订阅,则必须实现IMyServiceCallback接口

票数 0
EN

Stack Overflow用户

发布于 2013-01-30 09:14:54

我修复了回调指令嵌入到函数调用中时的问题。我了解到,将回调放在不返回结果的方法中可以很好地工作。然而,当回调指令被放在函数中时,我遇到了超时问题。

我通过在被调用的函数中使用backgroundworker线程解决了这个问题:

代码语言:javascript
代码运行次数:0
复制
public static IMyServiceCallback Callback;
.
.
.

        TaskStateData taskStateData = GetSomeData();

        BackgroundWorker backgroundWorker = new BackgroundWorker();

        backgroundWorker.DoWork += (se, ev) =>
            {
                Tuple<OperationContext, TaskStateData> data = ev.Argument as Tuple<OperationContext, TaskStateData>;
                var operationContext = data.Item1;

                if (operationContext != null)
                {
                    Callback = operationContext.GetCallbackChannel<IMyServiceCallback>();
                    Callback.OnCallBack();
                }
            };

        Tuple<OperationContext, TaskStateData> payload = new Tuple<OperationContext, TaskStateData>(OperationContext.Current, taskStateData);
        backgroundWorker.RunWorkerAsync(payload);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9922174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档