2012-07-30 47 views
2

我不太确定如何处理我以良好的代码方式处理场景。在每个会话中消费WPF应用程序中的WCF服务

基本的我工作的标准是这样的:

    消耗WCF服务
  • 每个会话实例化服务使用
  • WPF应用程序
  • 会话应用程序启动后不久开始,应该在整个应用程序生命周期中生存(但很少例外)
  • 会话中的某些方法调用必须在调用之前完成并完成其他调用

这意味着我必须能够在整个应用程序中拥有一个代理客户端实例。我还必须能够处理异步呼叫,所以客户端不会挂断,但同时确保它们完成。

我的技术理解去WCF足够限制,不知道某些场景是否会按预期工作。所以我要列出我的不确定性:

  • 什么时候会话开始,什么时候结束。它是基于创建客户端还是单独的客户端实例访问同一个会话,如果第一个会失败。
  • 什么是通过WCF服务处理异常的最佳方式
  • 是我应该看看以帮助我放在这里的ChannelFactory。

那么我在第一次迭代中试图解决这些问题。

  • 我使用依赖注入为我的WPF应用程序(我使用MVVM)的类注入客户端实例,以确保相同的实例无处不在。
  • 我使用异步生成方法来获取服务引用,以获取所有方法的Begin和End版本,以确保调用将是异步的我使用Caliburn.Micro框架的Coroutine(IResult接口)功能来确保一个异步动作在另一个异步动作开始之前完成(不知道这是否是正确的用法,或者它是否是一个聪明的动作)。

问题我还有当然是如何处理客户端的故障状态。我现在假设我可以恢复客户端并挽救会话,或者我可以重新设置它。我现在需要将它注入到同一个新实例中的每个位置。

所以我虽然也许最好创建一个ClientManager类来封装客户端。这样我可以注入这个ClientManager并在需要时恢复他。我想我应该向外暴露他能够进行方法调用,但如果我能以某种方式错误地处理他,那将是非常好的。我只是很难测试我的方法,我从不肯定它会在集成中正常工作,因为我不了解WCF,协程和线程的所有内部工作原理。

有没有人有更多的经验,然后我在这些事情,可以给我几个指针或至少告诉我WCF如何在这些情况下(每个会话)以及我做错了什么和什么是正确的。

回答

1

WCF支持开箱即用会话,所以我建议从this开始MSDN文章。

在非常高的水平上,首先在ServiceContract中设置SessionMode=SessionMode.Required。然后,在OperationContract's上设置IsInitiating=TrueIsTerminating=True属性以标记每个会话的开始和结束。

但是,请注意,默认情况下,WCF将并发会话限制为16以防止DOS attacks,但您始终可以调高该值。此外,只要其主机(IIS/Windows Service/other)未被回收,您就会意识到该会话是有效的。

在相关说明中,我之前使用过WCF Durable Services--这意味着将WCF服务的状态保存在数据存储区中(默认为SQL Server)。当然,这里有一个表现。建议阅读further,看看这是否是您的正确选择。

希望这会有所帮助。

+0

是的服务正在使用一个开箱即用的会话实例。我不确定的是本次会议何时开始,何时结束。你提到那些IsInitiating和IsTerminating属性,我会研究它们。所以我可以创建会话,但如果我创建客户端的新实例,我该如何告诉它拦截该特定会话。 – 2012-07-30 17:19:29

+0

WCF中的会话不像ASP.NET那样表现为没有像HttpContext.Current.Session这样的全局API。你需要坚持你的WCF代理,但我知道一旦它发生故障就会丢失。我在WCF代理中保留和恢复状态的方法最接近我通过Durable Services。 [这](http://weblogs.asp.net/gsusx/archive/2007/06/14/orcas-durable-services.aspx)博客文章会给你更多的细节,如果你有兴趣。 – Channs 2012-07-30 17:41:54

+0

嗯,耐用的服务似乎坚持服务,但我不在乎这一点。我只是希望Service对象的实例保持活动状态,即使clientProxy死亡并且新的clientproxy应该能够连接到它。 – 2012-07-31 11:45:56