管理频繁数据库轮询的好的C#.NET解决方案

11

我目前正在开发一个使用c#.NET桌面应用程序,通过WCF和WCF数据服务连接互联网上的数据库。在应用程序中有许多地方可能需要定时刷新,最简单的解决方案是将这些区域放置在计时器上并重新查询数据库。但是,由于有数千个客户端连接到服务层和数据库,因此这些操作对服务器来说非常昂贵。

我的考虑是创建一个RSS订阅源,由客户端轮询,并告知客户端什么时间需要更新这些特定区域。RSS订阅源将由服务管理,该服务会轮询数据库进行更改,或迭代由客户端发起的WCF请求排队的项目列表。

我还考虑创建一些直接和连续的客户端到服务器的连接,但我不确定客户端出站防火墙端口是否打开。我可能只能指望端口80/443。

所以我的问题是,人们已经成功采用哪些解决方案来解决这个问题?有人做过RSS吗?Microsoft Sync Services?通过WCF在某个保存端口上实现客户端和服务器之间的双向通信?

5个回答

8
我认为您可能需要采用两种方法的组合。首先,您可以使用长轮询从客户端到服务器,以便服务器可以在发生客户端感兴趣的更改时立即通知客户端。
ASP.NET中一个很好地处理上述建议的新技术是SignalR。这处理了大部分长轮询的细节(或在可以使用WebSockets时使用),因此您不必担心它。
其次,基于问题中的标签,看起来您正在使用SQL Server。您可以在您感兴趣的表上使用数据库通知,以使DB在发生更改时通知您的服务。然后,这可以通过长轮询连接触发服务向客户端通知更改。您可以使用SqlDependency类来实现此操作。
我相信还有其他方法,但这可能会很好地扩展,因为您只需一个服务即可获取通知,然后将其分发给所有客户端。

+1,但我担心成千上万的客户端使用长轮询。为了保持开放连接,可能需要进行一些环境优化。我从未在WCF中完成过这项工作,因此无法对难点/优点发表评论。 - marr75
+1 你知道使用WCF的C#有哪些好的长轮询实现吗?我尝试了谷歌搜索,但没有找到好的例子。 - BernicusMaximus
抱歉,我不知道。我知道在Silverlight中有一个Duplex通道的WCF,但据我所读,它会定期轮询而不是进行长轮询(http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx)。 - Jeremy Wiebe
是的,看到了同样的事情。再次感谢。 - BernicusMaximus

5
您可以在WCF连接中定义回调接口,如下所示:

您可以在WCF连接中定义回调接口,如下所示:

[ServiceContract(CallbackContract = typeof(IFooClient))]

当客户端启动连接时,它应该通过防火墙工作。然后,服务器可以使用方法来注册更改,并且您可以获得回调接口。

IFooClient client = OperationContext.Current.GetCallbackChannel<IFooClient>();

并回调所有已注册的客户端以响应数据更改。

我也喜欢这种方法。我会进一步调查它。 - BernicusMaximus

0
如果昂贵的操作是服务器池化数据库,您应该实现某种缓存。它可以是基本的ASP.NET缓存或高级的使用memcached。
但是,如果昂贵的操作是客户端池化服务器,则可以使用Atom或RSS提要与PubSubHubbub一起使用,以最小化对服务器的请求次数。由于有一些免费的PubSubHubbub发布者将处理负载,因此它会变得更便宜。

0

你可以研究一下 Service Broker,这样你就不需要轮询更新了。


0

我不知道为什么RSS会比从数据库中缓存信息的Web服务更简单。

为了比较这两个选项,假设您需要知道谁最后编辑了报告中的对象(或者上次更新时间等)。使用RSS订阅,您需要请求订阅,获取它,解析它,并根据相关值采取行动。而对于一个备忘录化并缓存其数据库调用的Web服务调用,您只需调用该服务并对结果采取行动。我唯一能想到RSS更好的时候是:1)您正在支持多个客户端,您无法控制或不是.Net客户端;2)您正在基于同时轮询的大量值采取行动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接