如何使用后台工作线程创建WCF服务?

时间:2012-06-30 13:25:26

标签: wcf backgroundworker

我有一个WCF服务,所有客户端都连接到该服务以获取通知\提醒(使用他们实现的CALLBACK接口)。目前,WCF服务是自托管的,但计划是将其托管在Windows服务中。

WCF服务具有“发布”,“订阅”和“取消订阅”操作。

我需要有一个后台工作线程某种类型的查询SQL服务器数据库表[每隔XXX分钟],并查找某些“提醒”行。一旦找到它们 - 它应该通知所有连接的客户端。

我想到了实现这个目标的两种方法。

方法A:

有一个单独的EXE项目(不要让它成为一个控制台,那应该是什么 - 一个Windows服务?),它将启动并运行一个后台线程。后台线程将作为其客户端之一连接到“Reminder”服务。后台线程将轮询数据库,一旦找到某些内容 - 它将向WCF服务发送'发布'消息,这将使WCF服务向所有订阅的客户端发送提醒。

方法B:

以某种方式使后台线程在 WCF服务项目中运行 ,当它在数据库中检测到新的提醒行时,以某种方式让它“发出信号”WCF服务使用该信息,然后WCF服务将此信息发送给所有订阅的客户端。

哪种方法更好?还有其他建议吗?

2 个答案:

答案 0 :(得分:6)

如果这是一个长时间运行的过程,Windows服务是一个完美的解决方案。 您的主要Win Service线程将轮询数据库,将结果排入某种供应商/消费者线程安全集合。

您可以在win服务中托管WCF服务,然后可以使用(删除)队列中的任何结果并按照请求将它们传递回客户端(调用WCF将在他们自己的线程中进行)

这是一种非常常见的架构,并不难实现。

答案 1 :(得分:1)

方法A:

如果您要创建两个单独的主机(即一个用于WCF服务,一个用于“轮询”服务),那么您实际上只有一个选项可以使它完全正常工作。

Windows服务通信非常有限(没有服务端点的帮助,例如WCF)。因此,如果您要在Windows服务中托管“轮询”服务,则必须将其与WCF服务结合使用。

然后可以在一个Windows服务中同时托管这两个服务,并通过手动实例化WCF主机并将“轮询”服务传递给构造函数。

protected override void OnStart(string[] args)
{
    //...

    // This would be you "polling" service that would start a background thread to poll the db.
    var notificationHost = new PollingService();
    // This is your WCF service which you will be "self hosted".
    var serviceHost = new WcfService(notificationHost);

    new ServiceHost(serviceHost).Open();
    //...
}

这远非理想,因为您需要通过两个服务之间的事件进行通信,而且您的WCF服务必须在单例模式下运行才能进行手动实例化...所以这会让您... ...

方法B:

如果您要在WCF服务中托管“轮询”服务,那么您将遇到许多问题。

  1. 您需要了解创建的“轮询”服务的实例数。如果您的WCF服务已配置为针对每个会话进行实例化,则最终可能会有太多“轮询”服务,最终可能会导致数据库/服务器被杀死。
  2. 为了避免第一个问题,您可能需要设置单例WCF服务,这可能会在不久的将来导致扩展问题,其中一个WCF服务实例不足以处理连接请求的数量。
  3. 方法C:

    鉴于方法A和方法B的缺点,最好的解决方案是托管两个独立的WCF服务。

    1. 这是您订阅/取消订阅/发布的常规服务。
    2. 这是您使用subscribe / unsubscribe的轮询单件服务。
    3. 我们的想法是,您的常规服务在收到订阅者后将打开与您的轮询服务的新连接或使用现有服务(取决于您配置会话的方式)并等待回复。您的轮询服务是一个长期运行的WCF服务,它会轮询您的数据库并将通知发布给其订阅者(即其他WCF主机)。

      <强>优点:

      1. 您可以放心,只有一个投票服务。
      2. 您可以扩展解决方案以承载IIS中的常规服务和Windows服务中的轮询服务。
      3. 两种服务之间的通信限制很小,不需要事件。
      4. 通过接口以相互依赖的方式测试每项服务。
      5. 服务之间的低耦合和高内聚(这是我们想要的!)。
      6. <强>缺点:

        1. 更多服务意味着需要维护更多接口和合同。
        2. 更高的复杂性。