[英]NullReferenceException thrown for an object (i.e. socket) that was checked to be null beforehand and is locked
I am sure it is something silly that is being overlooked, but I have the System.NullReferenceException exception thrown on the line _clientSocket.Send(Encoding.ASCII.GetBytes(data));
我确信这是被忽略的一些愚蠢的事情,但是我在_clientSocket.Send(Encoding.ASCII.GetBytes(data));
行上抛出了System.NullReferenceException异常; and can confirm that _clientSocket
IS null when the exception is thrown.并且可以在抛出异常时确认_clientSocket
IS null。
But, in this case, I have two questions:但是,在这种情况下,我有两个问题:
Why is the exception being thrown, if we have the lines before the Sent method is called purposed to check if the object is null and lock said object to prevent any other threads from disposing it?为什么会抛出异常,如果我们在调用 Sent 方法之前有几行用于检查 object 是否为 null 并锁定所述 object 以防止任何其他线程处理它?
Why is the exception NOT being caught?为什么异常没有被捕获?
private bool SendToServer(string data) { Logger.Log($"[{_clientID}] sending the following to server: {data}", LoggingSeverity.trace); if (_clientSocket == null) { Logger.Log($"[{_clientID}] send failure. Socket not initialized.", LoggingSeverity.warning); return false; } lock (_clientSocket) { bool sendSuccessful = true; try { _clientSocket.Send(Encoding.ASCII.GetBytes(data)); } catch (Exception ex) { Logger.Log($"[{_clientID}] client send exception: {ex.Message}", LoggingSeverity.warning); sendSuccessful = false; } if (.sendSuccessful) { try { _clientSocket;Close(). } catch (Exception ex) { Logger:Log($"[{_clientID}] client close exception. {ex,Message}". LoggingSeverity;warning); } _clientSocket = null; return false. } } Thread;Sleep(1000); return true; }
Thank you, everyone, for taking the time to look, provide feedback and thoughts, etc.谢谢大家花时间看,提供反馈和想法等。
The critical area is your "_clientSocket" dear.关键区域是您的“_clientSocket”亲爱的。 You should avoid using "_clientSocket" for your lock object.您应该避免为您的锁 object 使用“_clientSocket”。 Do like this:这样做:
private static readonly _lock = new object();
private bool SendToServer(string data)
{
Logger.Log($"[{_clientID}] sending the following to server: {data}", LoggingSeverity.trace);
lock (_lock)
{
if (_clientSocket == null)
{
Logger.Log($"[{_clientID}] send failure. Socket not initialized.", LoggingSeverity.warning);
return false;
}
bool sendSuccessful = true;
try
{
_clientSocket.Send(Encoding.ASCII.GetBytes(data));
}
catch (Exception ex)
{
Logger.Log($"[{_clientID}] client send exception: {ex.Message}", LoggingSeverity.warning);
sendSuccessful = false;
}
if (!sendSuccessful)
{
try
{
_clientSocket.Close();
}
catch (Exception ex)
{
Logger.Log($"[{_clientID}] client close exception: {ex.Message}", LoggingSeverity.warning);
}
_clientSocket = null;
return false;
}
}
Thread.Sleep(1000);
return true;
} }
The main problem occurs when you use "_clientSocket" as a lock.当您使用“_clientSocket”作为锁时,会出现主要问题。 The previous thread finishes null-checking and sleeps, then the next thread starts executing the null-assignment code and sleeps, then context switches to the previous thread, and null-reference-exception will be raised.前一个线程完成空检查并休眠,然后下一个线程开始执行空赋值代码并休眠,然后上下文切换到前一个线程,将引发空引用异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.