SignalR Hub 抛出 NRE
SignalR Hub throws NRE
我遇到空引用异常问题,无法理解为什么会发生这种情况。这是我的中心
public class UserHub : Hub
{
private static List<Connection> Users = new List<Connection>();
public override async Task OnConnected()
{
string id = Context.ConnectionId;
string userName = Context.User.Identity.Name;
if (Users == null)
Users = new List<Connection>();
if (!Users.ToArray().Any(_ => _.UserName == userName))
Clients.AllExcept(Context.ConnectionId).onNewUserConnected(id, userName);
if (!Users.ToArray().Any(x => x.ConnectionId == Context.ConnectionId))
Users.Add(new Connection { ConnectionId = id, UserName = userName });
Clients.Caller.onConnected(id, userName, Users.DistinctBy(_ => _.UserName).ToList());
await base.OnConnected();
}
public override async Task OnReconnected()
{
string id = Context.ConnectionId;
string userName = Context.User.Identity.Name;
if (Users == null)
Users = new List<Connection>();
if (!Users.Any(_ => _.UserName == userName))
Clients.AllExcept(Context.ConnectionId).onNewUserConnected(id, userName);
if (!Users.Any(x => x.ConnectionId == id))
Users.Add(new Connection { ConnectionId = id, UserName = userName });
Clients.Caller.onConnected(id, userName, Users.DistinctBy(_ => _.UserName).ToList());
await base.OnReconnected();
}
public override async Task OnDisconnected(bool stopCalled)
{
if (Users == null)
Users = new List<Connection>();
var item = Users.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
Users.Remove(item);
Clients.All.onUserDisconnected(Context.ConnectionId, item.UserName);
await base.OnDisconnected(stopCalled);
}
}
问题发生在 onConnected 方法中,在这一行:
if (!Users.ToArray().Any(_ => _.UserName == userName))
我已经尝试在上面添加 null 检查,但它不起作用。怎么了?该问题随机出现。
堆栈跟踪:
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at App.Web.Hubs.UserHub.<OnConnected>d__1.MoveNext() in E:\Company\App\App\Presentation\App.Web\Hubs\UserHub.cs:line 49
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
...
您的代码不是线程安全的,因此您在访问 Users
列表时会遇到各种问题。多个连接可以同时启动或关闭,它们都在访问静态 Users
属性。访问列表时考虑使用并发数据结构或锁。
我遇到空引用异常问题,无法理解为什么会发生这种情况。这是我的中心
public class UserHub : Hub
{
private static List<Connection> Users = new List<Connection>();
public override async Task OnConnected()
{
string id = Context.ConnectionId;
string userName = Context.User.Identity.Name;
if (Users == null)
Users = new List<Connection>();
if (!Users.ToArray().Any(_ => _.UserName == userName))
Clients.AllExcept(Context.ConnectionId).onNewUserConnected(id, userName);
if (!Users.ToArray().Any(x => x.ConnectionId == Context.ConnectionId))
Users.Add(new Connection { ConnectionId = id, UserName = userName });
Clients.Caller.onConnected(id, userName, Users.DistinctBy(_ => _.UserName).ToList());
await base.OnConnected();
}
public override async Task OnReconnected()
{
string id = Context.ConnectionId;
string userName = Context.User.Identity.Name;
if (Users == null)
Users = new List<Connection>();
if (!Users.Any(_ => _.UserName == userName))
Clients.AllExcept(Context.ConnectionId).onNewUserConnected(id, userName);
if (!Users.Any(x => x.ConnectionId == id))
Users.Add(new Connection { ConnectionId = id, UserName = userName });
Clients.Caller.onConnected(id, userName, Users.DistinctBy(_ => _.UserName).ToList());
await base.OnReconnected();
}
public override async Task OnDisconnected(bool stopCalled)
{
if (Users == null)
Users = new List<Connection>();
var item = Users.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
Users.Remove(item);
Clients.All.onUserDisconnected(Context.ConnectionId, item.UserName);
await base.OnDisconnected(stopCalled);
}
}
问题发生在 onConnected 方法中,在这一行:
if (!Users.ToArray().Any(_ => _.UserName == userName))
我已经尝试在上面添加 null 检查,但它不起作用。怎么了?该问题随机出现。
堆栈跟踪:
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
at App.Web.Hubs.UserHub.<OnConnected>d__1.MoveNext() in E:\Company\App\App\Presentation\App.Web\Hubs\UserHub.cs:line 49
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
...
您的代码不是线程安全的,因此您在访问 Users
列表时会遇到各种问题。多个连接可以同时启动或关闭,它们都在访问静态 Users
属性。访问列表时考虑使用并发数据结构或锁。