问题描述
我有一个 Windows 服务,它使用一堆文件的名称并对它们进行操作(压缩/解压缩、更新数据库等).操作可能需要一些时间,具体取决于发送到服务的文件的大小和数量.
I have a Windows Service that takes the name of a bunch of files and do operations on them (zip/unzip, updating db etc). The operations can take time depending on size and number of files sent to the service.
(1) 向该服务发送请求的模块会等待文件处理完毕.我想知道是否有办法在服务中提供回调,以便在完成处理文件时通知调用模块.请注意,多个模块可以一次调用该服务来处理文件,因此我猜该服务需要提供某种 TaskId.
(1) The module that is sending a request to this service waits until the files are processed. I want to know if there is a way to provide a callback in the service that will notify the calling module when it is finished processing the files. Please note that multiple modules can call the service at a time to process files so the service will need to provide some kind of a TaskId I guess.
(2) 如果一个服务方法被调用并正在运行,而另一个调用是对同一个服务的,那么将如何处理该调用(我认为只有一个线程与该服务相关联).我已经看到,当服务花时间处理方法时,与服务关联的线程开始增加.
(2) If a service method is called and is running and another call is made to the same service, then how will that call be processed(I think there is only one thread asociated with the service). I have seen that when the service is taking time in processing a method, the threads associated with the service begin to increase.
推荐答案
WCF 确实提供了双工绑定,允许您指定回调协定,以便服务可以回调调用客户端进行通知.
WCF does indeed offer duplex bindings which allow you to specify a callback contract, so that the service can call back to the calling client to notify.
然而,在我看来,这种机制相当脆弱,并不值得推荐.
However, in my opinion, this mechanism is rather flaky and not really to be recommended.
在这种情况下,当调用导致一个相当长的运行操作发生时,我会做这样的事情:
In such a case, when the call causes a fairly long running operation to happen, I would do something like this:
如果您想坚持使用 HTTP/NetTcp 绑定,我会:
If you want to stick to HTTP/NetTcp bindings, I would:
- 放下服务的请求,然后放手"——这将是一个单向调用,你只需放下你想做的事情,然后你的客户就完成了
- 有一个状态调用,客户端可以在给定的时间后调用它来确定请求的结果现在是否准备好
- 如果是,则应该有第三个服务调用来检索结果
因此,在您的情况下,您可以放弃压缩某些文件的请求.该服务将关闭并执行其工作并将生成的 ZIP 存储在临时位置.然后客户端可以检查 ZIP 是否准备好,如果是,则检索它.
So in your case, you could drop off the request to zip some files. The service would go off and do its work and store the resulting ZIP in a temporary location. Then later on the client could check to see whether the ZIP is ready, and if so, retrieve it.
这比每台 Windows 服务器机器中都存在的消息队列 (MSMQ) 效果更好(但似乎没有多少人知道或使用它):
This works even better over a message queue (MSMQ) which is present in every Windows server machine (but not a lot of people seem to know about it or use it):
- 您的客户将请求放到请求队列中
- 该服务侦听该请求队列并在请求后获取请求并使其正常工作
- 然后该服务可以将结果发布到结果队列,您的调用者依次监听该队列
通过阅读优秀的 MSDN 文章Foudnations,了解如何有效地完成所有这些工作:构建队列 WCF 响应服务 - 强烈推荐!
Check out how to do all of this efficiently by reading the excellent MSDN article Foudnations: Build a queue WCF Response Service - highly recommended!
在我看来,基于消息队列的系统往往比基于双工/回调契约的系统更稳定且不易出错.
A message-queue based systems tends to be much more stable and less error-prone that a duplex-/callback-contract based system, in my opinion.
这篇关于WCF Windows 服务 - 长操作/回调调用模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!