【问题标题】:C# error System.NullReferenceExceptionC# 错误 System.NullReferenceException
【发布时间】:2014-02-22 00:14:22
【问题描述】:

我对 System.NullReferenceException 有一些问题。当服务器执行操作时,我们首先检查用户是否为空,然后他断开连接并且服务器进行某些操作,并尝试获取用户来 System.NullReferenceException。我有超过 20 000 行代码,所以我需要一些小的东西,而不是总是检查它是否为空。我的服务器是多线程的,所以套接字在后台始终获取连接并断开用户的连接,这就是为什么会出现这种情况。我想在用户断开连接时停止该进度.如果我把“try/catch”放在任何地方,那是好方法吗?

例子:

if (User != null)
{
    //do some things
    System.Threading.Thread.Sleep(1000); //now we have time disconnect (This only for get error)
    User.SendMessage("crash"); //<-- System.NullReferenceException... -.-
}

【问题讨论】:

  • @SonerGönül 您的链接没有说明如何解决这个特定问题
  • 20 000 行代码-->如果你有适当的架构,并且如果它的全部在一个方法中进行折射,那么除了检查 null 以避免 null 异常之外别无他法
  • @user3290224.. 而不是 sleep.. 以后台工作人员身份运行您的代码

标签: c# nullreferenceexception


【解决方案1】:

看起来User 的值在测试之后但在调用SendMessage 之前发生了变化。如果您的应用程序是多线程的,我怀疑在您睡觉时另一个线程正在将 User 设置为 null。

一种选择是获取User 并对其进行检查:

var user = User;
if (user != null)
{
    //do some things
    System.Threading.Thread.Sleep(1000);get error)
    user.SendMessage("crash"); // Need to be sure user is in a valid state to make call
}

这样您就可以确定您有一个有效的参考。您现在需要做的是确保user 处于有效状态,您可以调用SendMessage

更新:由于您一直避免添加 try/catch 块,您可以编写一个辅助函数:

void WithUser(Action<User> action)
{
  try
  {
     var user = User;
     if (user != null) action(user);
  }
  catch(Exception e)
  {
    // Log it...
  }
}

现在你可以说:

WithUser(user=>
{
  System.Threading.Thread.Sleep(1000);
  user.SendMessage("crash");
});

【讨论】:

  • Hmmm.. 是那个 var goodway 因为示例 User.GetClient() 也被调用,所以如果用户断开连接,它返回太空
  • @user3290224 - 我不太理解您的评论,但这是在多线程应用程序中处理属性变为null 的合理方法。您需要做的是确保对象在调用它时处于有效状态,因此您可能必须用try/catch 块包围它。
  • 尝试/捕获 20 000 行?我的意思是当用户断开连接并且服务器需要它时,还有其他函数会变为空,例如 GetClient()
  • 抱歉我的回答太慢了,因为我睡着了。那条好方法是否将其与 20 000 行代码一起使用?有很多很长的功能会使用很多时间用户等。“尝试”可以让我的服务器变慢吗?
  • 除非有异常,否则不会影响性能。您需要停止担心您有多少代码(20,000 也不算多),并开始考虑如何使您的应用程序没有错误。不是说你必须尝试\catch每一行代码,是不是……!
【解决方案2】:

谁将User 设置为空,在哪里?当您的线程休眠时,显然有人将 User 变量设置为 null,从而导致崩溃。

此外:“神奇的睡眠”不会解决任何问题。您需要在这里正确锁定。

【讨论】:

  • 套接字断开连接将用户设置为空,我的程序是多线程的,所以它可以随时发生。睡眠就是一个例子,因为它的努力尝试得到那个错误,因为服务器在毫秒内做事,但不会停止每天超过 100 个 System.NullReferenceException ;/
  • 那么你需要实现适当的锁定。在多线程环境中单独测试 null 是行不通的。
【解决方案3】:

SendMessage 抛出空异常,检查SendMessage 方法中的代码

如果User 在调用之前变为空,则不要调用 SendMessage:-

 if (User != null)
 {
       User.SendMessage("crash"); //<-- No More System.NullReferenceException... -.-
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多