我在WPF客户端中自托管WCF服务。我想显示服务在用户界面中收到的数据。每次收到一些数据时,都应该更新用户界面。
“App.xaml.cs”中的代码如下所示
private ServiceHost _host = new ServiceHost(typeof(MyService));
private void Application_Startup(object sender, StartupEventArgs e)
{
_host.Open();
}
private void Application_Exit(object sender, ExitEventArgs e)
{
_host.Close();
}
如何从托管WPF应用程序获取实现服务合同的对象实例?
感谢大家的答案。
我没有看到ServiceHost的构造函数允许传递服务的实例而不是类型。
所以我现在所做的是:
结果:单例WCF服务中的每个更新都反映在UI中。
快乐!
答案 0 :(得分:13)
正如marc_s所说,您正在创建PerCall / PerSession WCF服务,并且会在每个会话的每个请求/第一个请求上创建一个新实例。
你可以在它周围构建一些管道,以便实例在收到新请求时可以通知服务主机,但这不是一个简单的练习,如果你决定你需要注意内存泄漏的可能性继续使用事件来执行此操作 - 不实现弱事件模式您的WCF服务实例可能会被搁置,因为事件处理程序仍然保留对它们的引用,除非您记得在处理WCF服务实例时通知主机取消订阅。
相反,这里有两个可能让您更容易实现目标的想法:
如果您的服务可以成为单身人士,请使用单一 InstanceContextMode,在这种情况下,您将创建一个实施服务合同并托管服务合同的新实例:
// instance will be your WCF service instance
private ServiceHost _host = new ServiceHost(instance);
这样您就可以访问将检索客户端请求的实例。
或者,你可以让所有托管的实例都是虚拟的'fascades',它们共享一个实际处理请求的静态类:
[ServiceContract]
interface IMyService { ... }
interface IMyServiceFascade : IMyService { ... }
// dummy fascade
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall]
public class MyServiceFascade : IMyServiceFascade
{
private static IMyService _serviceInstance = new MyService();
public static IMyService ServiceInstance { get { return _serviceInstance; } }
public int MyMethod()
{
return _serviceInstance.MyMethod();
}
...
}
// the logic class that does the work
public class MyService : IMyService { ... }
// then host the fascade
var host = new ServiceHost(typeof(MyServiceFascade));
// but you can still access the actual service class
var serviceInstance = MyServiceFascade.ServiceInstance;
如果可能的话,我会说你应该采用第一种方法,让生活更轻松!
答案 1 :(得分:1)
没有一个类型为MyService
的对象实例可用 - 默认情况下,WCF使用每个呼叫模型,例如:对于每个进入的请求,将创建一个MyService
的新实例,用于处理该请求,然后释放。
因此,除非至少有一个正在运行的请求,否则很可能没有任何服务实例。
你想用这个完成什么?也许您需要重新考虑您的方法并从服务类实例开始 - 它有一个属性.Host
,它链接回托管该特定服务实例的主机。