【问题标题】:System.InvalidOperationException when calling WCF Service调用 WCF 服务时出现 System.InvalidOperationException
【发布时间】:2014-08-13 09:42:50
【问题描述】:

我正在尝试使用 netTcpBinding 创建 WCF 回调服务。当我尝试调用服务的方法时,出现以下异常:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll

Additional information: The InstanceContext provided to the ChannelFactory contains a UserObject that does not implement the CallbackContractType 'Client.WCFService.IHostFunctionsCallback'.

我添加了一个服务引用,而不是使用 SvcUtil.exe 我已经在互联网上搜索了解决此问题的方法,但我还没有找到解决方案。

这是我的实现:

IHostFunctions.cs(HostLibrary 的一部分)

using System.ServiceModel;

namespace HostLibrary
{
    [ServiceContract(CallbackContract = typeof(ICallback))]
    public interface IHostFunctions
    {
        [OperationContract]
        void OpenSession();
    }
}

ICallback.cs(HostLibrary 的一部分)

using System.ServiceModel;

namespace HostLibrary
{
    public interface ICallback
    {
        [OperationContract]
        void OnCallback();
    }
}

HostFunctions.cs(HostLibrary 的一部分)

using System;
using System.ServiceModel;
using System.Timers;

namespace HostLibrary
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class HostFunctions : IHostFunctions
    {
        #region Implementation of IHostFunctions

        public static ICallback Callback;
        public static Timer Timer;

        public void OpenSession()
        {
            Console.WriteLine("> Session opened at {0}", DateTime.Now);
            Callback = OperationContext.Current.GetCallbackChannel<ICallback>();

            Timer = new Timer(1000);
            Timer.Elapsed += OnTimerElapsed;
            Timer.Enabled = true;
        }

        void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            Callback.OnCallback();
        }

        #endregion
    }
}

Callback.cs(客户端的一部分)

using System;
using HostLibrary;

namespace Client
{
    public class Callback : ICallback
    {
        #region Implementation of ICallback

        public void OnCallback()
        {
            Console.WriteLine("> Received callback at {0}", DateTime.Now);
        }

        #endregion
    }
}

服务的Program.cs

using System;
using System.ServiceModel;
using HostLibrary;

namespace WCF_TCP_Callbacks
{
    internal static class Program
    {
        private static void Main(string[] args)
        {
            using (var sh = new ServiceHost(typeof (HostFunctions)))
            {
                sh.Open();
                Console.WriteLine("Service started.");

                Console.ReadLine();
                Console.WriteLine("Stopping service...");
                sh.Close();
            }
        }
    }
}

客户端的Program.cs

using System;
using System.Globalization;
using System.ServiceModel;
using System.Threading;
using Client.WCFService;

namespace Client
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var callback = new Callback();
            using (var proxy = new HostFunctionsClient(new InstanceContext(callback)))
            {
                proxy.OpenSession();
            }
            Console.ReadLine();
        }
    }
}

代码来自http://adamprescott.net/2012/08/15/a-simple-wcf-service-callback-example/,但带有 netTcpBinding。

【问题讨论】:

    标签: c# wcf callback


    【解决方案1】:

    默认情况下,WCF 将尝试使用可用的 SynchronizationContext 进行调度。此回调的问题是 UI 线程已在出站调用中被阻塞。所以对于调度调用,我们需要告诉 WCF 不要使用 SynchronizationContext——再次使用 CallbackBehavior 属性:

    [CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant, UseSynchronizationContext=false)]
    public class Callback : ICallback
    {
      ....
    }
    

    更多细节请看这个链接http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891610a-6b78-4b54-b9a6-4ec81c82b7c0.aspx 还有一篇文章进一步描述 http://stefanoricciardi.com/2009/08/28/file-transfer-with-wcp/

    【讨论】:

    • 我已经阅读了第一篇博文,但不幸的是添加 CallbackBehavior 仍然会导致该异常。
    • 基本上问题从netTCPBinding开始,你应该试试这个stackoverflow.com/questions/4534923/…他使用nettcpbinding完成的。
    【解决方案2】:

    我通过简单地将类 ICallback 重命名为 IHostFunctionsCallback 解决了这个问题。

    我仍然不知道为什么现在可以使用,因为我之前没有使用过IHostFunctionsCallback

    【讨论】:

      【解决方案3】:

      我知道帖子很旧: 你的回调类的真正名称是什么?

      您发布的代码是这样说的:

      Callback : ICallback
      

      错误消息是这样说的: CallbackContractType 'Client.WCFService.IHostFunctionsCallback'

      上面的代码中的回调也是如此,还是真的定义为:

      Client.WCFService.IHostFunctionsCallback
      

      我会说您错误地修饰了对回调通道的属性引用,或者从错误的回调继承。搜索您的项目以确保您正确命名所有内容。

      编辑 至于修复工作的原因以及发生了什么: 我回答了其他人的情况。如果您在团队环境中,有人将回调类接口的名称从如此通用更改为更易于理解的名称 - 在 WCF 中,这就是您的用户对象 - 它是合同。您可能曾经使用过 Visual Studio 来生成您的客户端或服务。这也可能使事情变得混乱,因为命名约定遵循 IService [Callback],所以在我看来就是这样。

      【讨论】:

      • 很遗憾,我不再为那家公司工作,而且我不记得代码了。
      猜你喜欢
      • 2010-12-11
      • 2014-08-24
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 2012-02-07
      相关资源
      最近更新 更多