SignalR 和 SqlDependency 刷新问题 - ASP.NET

SignalR and SqlDependency refreshment issue - ASP.NET

我在 MSSQL 数据库中有一个 table,并且我有一个 ASPX 页面,我需要按降序将所有新行推送到该页面。我发现 this awesome tutorial 正在使用 SignalR 和 SqlDependency,它只显示最后一行,去掉了我在线时添加的前几行,它这样做是因为它有一个 span 元素来显示数据,每次它覆盖这个跨度,所以我修改了 JavaScript 代码以附加新数据并且它工作正常。

现在的问题是,当我第一次刷新页面时,我会得到两次新行,如果我再次刷新页面,我会得到三次新行..等等。

唯一的解决办法就是关闭应用程序,然后重新打开,看来是重置了IIS。

那么,如何才能避免在线节目中出现重复数据呢?

这不是 SignalR 问题,这是因为提到的教程存在一系列错误,最明显的是它不断创建 SqlDependency 个实例,但随后将它们丢弃从不取消订阅 OnChange 事件。您应该首先添加如下内容:

SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= dependency_OnChange;

在事件处理程序中调用 SendNotifications 之前。检查 this 以获得一些灵感。

UPDATE(之前的回答不完全准确,但根据上下文保留)

这里的主要问题是这种技术从 Web 窗体页面的内部实例创建了一种自动重新生成 SqlDependencies 的无限序列,一旦页面完成呈现,它们就无法访问。这意味着,一旦您的页面生命周期完成并且页面被呈现,即使创建的页面实例已经完成其周期,依赖链仍然存在并继续工作。即使无法访问,事件处理程序也会使页面实例保持活动状态,从而导致内存泄漏。

你可以控制它的唯一方法实际上是在其他地方生成这些链,例如在静态类型中你可以调用传递一些唯一标识符(可能是页面名称和用户名的组合?这取决于你的逻辑) .在第一次调用时,它将执行您当前代码中当前发生的事情,但是一旦您使用相同的参数进行另一次调用,它将什么都不做,因此先前创建的链将继续成为唯一的通知链,不会重复调用.

这只是一个建议,会有很多可能的解决方案,但你需要了解最初的问题,以及如果你找不到办法,几乎不可能删除那些自动重新生成的依赖链的事实跟踪它们并仅在必要时创建它们。我希望那部分是清楚的。

PS:这种行为与您有时会遇到的事件非常相似,事件处理程序被泄漏并使应该被杀死的对象保持活动状态,这就是我用之前的答案愚弄的原因。它在某种程度上是一个类似的问题(泄漏的对象),但原因完全不同。您遵循的教程并没有阐明这一点,而是将您带到了 phantom 代码继续执行并且内存丢失的情况。

我明白了,虽然我绝对不喜欢这种方式,但我已经在 Global.asax 文件中声明了一个静态成员,并且在 Page_Load 事件中我检查了它的值,如果它是true 不要 运行 SqlDependency 的新实例,否则 运行 它。

if (!Global.PageIsFired)
            {
                Global.PageIsFired = true;
                SqlDependency.Stop(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
                SqlDependency.Start(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
                SendNotifications();
            }

亲爱的@Wasp, 你上次的更新对我理解问题有很大帮助,非常感谢你的时间和及时的支持。

亲爱的@dyatchenko, 非常感谢您的评论,它也很有用。