我正在使用WCF中的SOAP客户端与自托管的WCF服务进行通信,以远程控制我正在开发的一款软件。该软件的运行时间非常长(可以称之为Print
),运行时间可能会持续几分钟,也可能长达一小时。我试图找出如何实现方法Print
给出了以下要求:对长时间运行的服务器端方法实现客户端调用的正确方法
- 服务器应该能够筹集
FaultExceptions
到客户端,万一出了差错。 - 如果与服务的连接丢失,应尽快通知客户端。
- 如果断开连接,服务器端进程
Print
应该继续运行,以便客户端可以重新连接并继续监视进程并在必要时中止进程。
由于我是WCF的新手,我不确定如何实现这一点。我现在看到两种选择:
- 让
Print
一个async
方法,让我可以“射后不理”,直到它完成或抛出一个FaultException
。这看起来很直接,但我看到这个“问题”:WCF中有一个客户端请求超时,默认值为1分钟,这也适用于async
方法(如果我没有弄错)以及我将因此得到哪些大幅增加。这看起来有点像黑客。async
方法StartPringing
启动服务器端的任务打印和直接返回(或抛出一个异常的情况下,出现错误)和客户机 - - 通过拆分其行为为非实施的
Print
自己的async
行为回调方法PrintingFinished
。然后,我可以使用回调PrintingFinished
向客户端发出信号,当打印进程完成或使用额外的回调PrintingFailed
发送异常以防出现问题时。这个实现将被隐藏在async
方法Print
之后,因此它的行为方式可能会引发异常。在这里,我看到以下挑战:我将不得不实施整个异常回调 - 自己处理异常,以处理在StartPringing
返回后发生的异常(从StartPringing
本身我可以抛出FaultExceptions)。
对于这两种情况,我将不得不探讨如何检测,当连接被串联(我目前在服务上使用ping方法),然后以某种方式获取该事件以从内部抛出异常方法Print
。在实现方面,这看起来与备选方案(2)更加一致,因为我需要在打印过程完成或引发异常时实施所有其他事件处理程序。然而我不确定我会如何实现这个替代(1)。
那么,两种选择中的哪一种是“更好的”。更好地说,我的意思是以下考虑因素: 1.与WCF中的“标准”方式一致以实现如此长时间运行的方法。 2.可维护性和可扩展性。
如果我应该考虑任何其他选择,我会感激任何其他建议。
感谢您的回答。你能否详细说明一下,为什么你认为我需要MSMQ?我的印象是WCF中的请求被转移,如果没有,我会得到某种通信例外。详细阐述我的实现:我使用net.tcp绑定,所有通信都将在本地网络上进行。我不知道MSMQ(我是WCF新手),但MSMQ通信看起来还有更多工作需要实施。我想采用符合KISS原则的方法,因为我只有一个长时间运行的方法(如果需要的话忘记我的问题的可扩展性部分)。 – packoman
只是为了扩展我的评论以及为什么我犹豫不决:我已经使用net.tcp绑定解决了大部分实现细节。 “唯一”缺失(确实很大)的部分是我在问题中详细描述的方法的实现。所以这就是为什么我不愿意切换绑定而没有充分理由这样做。我会非常感谢您的意见... – packoman
感谢您的答案更新。因此,让我们假设我在开始打印过程之后跳过“异步”部分。我的想法是当连接丢失时,让Print方法抛出一个“断开”异常。然后,客户的工作是重新连接到服务并检查打印设备处于什么状态(即,“打印”是否仍在运行或完成)。我已经预见到诸如“打印机活动状态”之类的属性,客户端的用户可以使用它来检查打印机的状态并在重新连接后进行相应的操作。在这种情况下,我不需要MSMQ,对吗? – packoman