C# 信号员并发列表最佳实践

C# 信号员并发列表最佳实践,c#,signalr,C#,Signalr,我在一个MVC web应用程序中使用SignalR。我希望有一个对象列表UserDetail当前表单已验证的用户。此对象应保存来自表和ConnectionId信号器的用户ID Pk 今天,我在hub类中使用一个静态列表: public static List<UserDetail> ConcurrentUsers = new List<UserDetail>(); 当我想用一个用户的数据更新一个用户时,比如说他收到了一条新消息,然后我可以浏览列表,找到该用户的所有con

我在一个MVC web应用程序中使用SignalR。我希望有一个对象列表UserDetail当前表单已验证的用户。此对象应保存来自表和ConnectionId信号器的用户ID Pk

今天,我在hub类中使用一个静态列表:

public static List<UserDetail> ConcurrentUsers = new List<UserDetail>();
当我想用一个用户的数据更新一个用户时,比如说他收到了一条新消息,然后我可以浏览列表,找到该用户的所有connectionId,并将消息推送到所有连接的用户客户端

private static void FlushMessageToClient(Guid UserId, string Message)
{
    string[] cids = Hub.ConcurrentUsers.Where(x => x.UserId.Equals(UserId)).Select(x => x.ConnectionId).ToArray();
    foreach (string cid in cids)
    {
        Hub.Clients.Client(cid).messageReceived(Message);
    }
}
一切正常,直到网站运行一个小时并有输入和输出用户,它将开始接收错误:

System.NullReferenceException:对象引用未设置为实例 指一个物体。位于Infra.ChatHub.b_uu16userdetail System.Linq.Enumerable.Any[TSource]IEnumerable1源的x,Func2 位于ChatHub.IsUserAuthenticated的谓词


有更好的编程方法吗

如果您有索引键,我会使用字典:

Dictionary<Guid, UserDetail > dictionary = new Dictionary<Guid, UserDetail >();
关于您的错误,请在查询之前检查用户ID是否在列表中

if (dictionary.ContainsKey(userId)) {}

可以在下面找到最佳选项 将信号器用户映射到连接


请记住,每个用户ID都有许多ConnectionId,用户可以从不同的选项卡/浏览器登录。所以我需要快速可靠地访问所有connectionId的给定用户ID,反之亦然。然后,您可以使用struct userId、connectionID作为键。请参阅。UserId是键,但可以有多于1个connectionid。问题是您正在更新。在运行集合时添加。其中。您需要使用锁或更改为线程安全集合
dictionary.Add(userId, userDetail);   
var detail = dictionary[userId];
if (dictionary.ContainsKey(userId)) {}