这是我第一次玩SignalR。我正在尝试构建一个通知系统,服务器定期检查以查看是否有某些内容(查询数据库)要广播,如果有,则将其广播给所有客户端。 我遇到了 this post on Stackoverflow ,并且想知道修改代码是否以特定间隔进行数据库调用确实是正确的方法。如果不是,有更好的方法吗?
我确实在这里发布了许多与通知相关的问题,但没有任何代码。因此这篇文章。
这是我正在使用的确切代码:
public class NotificationHub : Hub
{
public void Start()
{
Thread thread = new Thread(Notify);
thread.Start();
}
public void Notify()
{
List<CDCNotification> notifications = new List<CDCNotification>();
while (true)
{
notifications.Clear();
notifications.Add(new CDCNotification()
{
Server = "Server A", Application = "Some App",
Message = "This is a long ass message and amesaadfasd asdf message",
ImgURL = "../Content/Images/accept-icon.png"
});
Clients.shownotification(notifications);
Thread.Sleep(20000);
}
}
}
我已经看到一些奇怪的行为,其中通知比预期更频繁。即使我应该每隔20秒就能得到它,我会在4-5秒左右得到它并且我收到多条消息。 这是我的客户:
var notifier = $.connection.notificationHub;
notifier.shownotification = function (data) {
$.each(data, function (i, sample) {
var output = Mustache.render("<img class='pull-left' src='{{ImgURL}}'/> <div><strong>{{Application}}</strong></div><em>{{Server}}</em> <p>{{Message}}</p>", sample);
$.sticky(output);
});
};
$.connection.hub.start(function () { notifier.start(); });
答案 0 :(得分:6)
几个笔记:
为了解决这个问题,你需要这样的东西(再次,Web应用程序中的线程通常不是一个好主意):
public class NotificationHub : Hub
{
public static bool initialized = false;
public static object initLock = new object();
public void Start()
{
if(initialized)
return;
lock(initLock)
{
if(initialized)
return;
Thread thread = new Thread(Notify);
thread.Start();
initialized = true;
}
}
public void Notify()
{
List<CDCNotification> notifications = new List<CDCNotification>();
while (true)
{
notifications.Clear();
notifications.Add(new CDCNotification() { Server = "Server A", Application = "Some App", Message = "This is a long ass message and amesaadfasd asdf message", ImgURL = "../Content/Images/accept-icon.png" });
Clients.shownotification(notifications);
Thread.Sleep(20000);
}
}
}
static 初始化标志可防止创建多个线程。它周围的锁定是为了确保标志只设置一次。
答案 1 :(得分:1)
我正在这里完成同样的任务。我没有连续检查数据库,而是创建了自己的事件和监听器,当添加通知时事件被提升了:)你对此有何看法?