【问题标题】:Event handler in SignalR hubSignalR 集线器中的事件处理程序
【发布时间】:2015-03-25 15:30:50
【问题描述】:

我面临以下问题。我有一个像这样的 SignalR 集线器:

public class NewsLetterHub : Hub
{
    private readonly IServicesContainer _servicesContainer;
    private readonly ILifetimeScope _hubLifetimeScope;

    public NewsLetterHub(ILifetimeScope lifetimeScope, IServicesContainer servicesContainer)
    {
        _servicesContainer = servicesContainer;
        _hubLifetimeScope = lifetimeScope.BeginLifetimeScope();

        _servicesContainer.NewsLetterService.ImportProgress += _sentNewsLetter_Progress;
    }

我以这种方式在 Autofac 中注册此集线器:

builder.RegisterHubs(Assembly.GetExecutingAssembly());

调试代码我看到每个请求都会调用一次集线器构造函数,但ImportProgress 事件包含之前注册的处理程序。这会导致_sentNewsLetter_Progress 方法被多次执行。

我尝试以这种方式注册集线器:

builder.RegisterHubs(Assembly.GetExecutingAssembly()).InstancePerLifetimeScope();

这样做似乎可行,但我不知道这是否是正确的解决方案(它变成了单例)。

我也尝试取消注册该活动:

_servicesContainer.NewsLetterService.ImportProgress -= _sentNewsLetter_Progress;
_servicesContainer.NewsLetterService.ImportProgress += _sentNewsLetter_Progress; 

但它似乎什么也没做。

如何防止这种行为?

【问题讨论】:

    标签: c# signalr autofac


    【解决方案1】:

    您需要更改要在析构函数或 Dispose() 方法中取消注册事件处理程序的位置。如果您尝试在构造函数中执行此操作,它将尝试从正在构造的实例中注销 _sentNewsLetter_Progress 处理程序。由于该实例尚未注册,因此它什么也不做。但是,如果您在析构函数/Dispose 中取消注册,那么它将起作用。

    【讨论】:

    • 除此之外,我不确定这是否是您正在寻找的设计。当 Progress 事件被触发时,您是否尝试向所有连接的客户端发布消息?如果是这样,您需要在某处的单例中注册一个事件处理程序(可能是集线器的静态构造函数)并调用类似GlobalHost.ConnectionManager.GetHubContext<NewsLetterHub>().Clients.All.progress() 的东西。有关示例,请参见 the SignalR documentation
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2013-11-23
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多