C# SignalR 1.1.3统计在线用户\连接、异常,有时不';行不通

C# SignalR 1.1.3统计在线用户\连接、异常,有时不';行不通,c#,asp.net-mvc,signalr,signalr-hub,C#,Asp.net Mvc,Signalr,Signalr Hub,基本上它可以工作,但有时会出现这些异常(总是在重新连接时打开): System.IndexOutOfRangeException:索引超出了数组的边界 System.InvalidOperationException:集合已修改;枚举操作不能执行 我想知道问题出在哪里(比如当你试图将foreach中的一项添加到同一个列表中时),但是我能做些什么来解决这个问题呢 代码: 公共类UsersHub:Hub { 专用结构信号发生器 { 公共字符串ClientId{get;set;} 公共字符串用户名{g

基本上它可以工作,但有时会出现这些异常(总是在重新连接时打开):

  • System.IndexOutOfRangeException:索引超出了数组的边界

  • System.InvalidOperationException:集合已修改;枚举操作不能执行

  • 我想知道问题出在哪里(比如当你试图将foreach中的一项添加到同一个列表中时),但是我能做些什么来解决这个问题呢

    代码:

    公共类UsersHub:Hub
    {
    专用结构信号发生器
    {
    公共字符串ClientId{get;set;}
    公共字符串用户名{get;set;}
    }
    静态IList用户=新列表();
    已连接的公用覆盖任务()
    {
    this.AddUser();
    返回base.OnConnected();
    }
    公共覆盖任务OnDisconnected()
    {
    this.RemoveUser();
    返回base.OnDisconnected();
    }
    已重新连接的公用覆盖任务()
    {
    this.AddUser();
    返回base.OnReconnected();
    }
    私有字符串GetClientId()
    {
    字符串clientId=“”;
    if(!(Context.QueryString[“clientId”]==null))
    {
    clientId=Context.QueryString[“clientId”].ToString();
    }
    如果(clientId.Trim()=“”)
    { 
    clientId=Context.ConnectionId;
    }
    返回客户ID;
    }
    私有void AddUser()
    {
    var user=Membership.GetUser();
    字符串clientId=GetClientId();
    如果(!users.Any(x=>x.ClientId==ClientId))
    {
    添加(新的信号器)
    {
    ClientId=ClientId,
    Username=user.Username
    });
    }
    }
    私有void RemoveUser()
    {
    字符串clientId=GetClientId();
    Remove(users.FirstOrDefault(x=>x.ClientId==ClientId));
    }
    }
    
    使用“锁定(用户)”解决,以防止不同线程可以同时修改用户

    例如:

    private void RemoveUser()
    {
        string clientId = GetClientId();
        lock(users)
        {
            users.Remove(users.FirstOrDefault(x => x.ClientId == clientId));
        }
    }
    
    private void RemoveUser()
    {
        string clientId = GetClientId();
        lock(users)
        {
            users.Remove(users.FirstOrDefault(x => x.ClientId == clientId));
        }
    }