我正在尝试使用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。
答案 0 :(得分: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/
答案 1 :(得分:0)
我通过简单地将课程ICallback
重命名为IHostFunctionsCallback
来解决该问题。
我仍然不知道为什么现在这样做,因为我之前没有使用IHostFunctionsCallback
。
答案 2 :(得分:0)
我知道帖子很旧: 您的回调类的名称是什么?
您发布的代码说:
Callback : ICallback
错误消息说明: CallbackContractType'Client.WCFService.IHostFunctionsCallback'
根据上面的代码,Callback也是如此,或者它真的定义为:
Client.WCFService.IHostFunctionsCallback
我会说你已经错误地修饰了回调通道的属性引用,或者从错误的回调继承。搜索您的项目以确保您正确命名所有内容。
修改强> 至于为什么修复工作和发生了什么: 我回答了其他人的情况。如果你在一个团队环境中,有人将Callback类接口的名称从如此通用更改为更容易理解的东西 - 在WCF中就是你的userobject - 它就是合同。您可能已使用Visual Studio一次生成客户端或服务。这也可以搞砸了,这就像我看来的那样,因为命名约定遵循IService [Callback]。