从公共字段读取我知道存在的对象的值时,我有一个令人难以置信的奇怪的NullReferenceException。 基本stream程是这样的:
编辑:我意识到我忘了提及一些重要的东西,每次我尝试读取Tag值时都不会发生这种情况,但是只有一次,足够我每次只需运行代码就可以重现它,而不是在代码运行时立即
服务器收到一条消息(Worker线程)
发送消息get的连接被设置为消息对象(工作线程)上的Tag字段
该消息被放入一个“ReceivedMessages”队列(一个正常的Queue对象,该对象被锁访问序列化) (Worker线程)
消息被读取(主线程)
我尝试读取消息的Tag字段以获得连接,这有时会返回null并引发exception,但是当抛出exception并检查Message对象时,可以看到Connection对象(它是Tag字段)有清晰的一天(主线程)
如果你看这张照片,你会看到清楚的一天:
我怎样才能从$(ProjectDir)中删除tralling反斜杠?
如何刷新未决的FileSystemWatcher事件?
如何设置.NET框架的作业调度?
我怎样才能找出谁在Windows中使用.NET创build一个文件?
吐司通知不能在Windows秋季创作者更新
你可以看到我用绿色框标记的位置,我试着用三种不同的方式阅读message.Tag属性,它们全都返回null,就像你在标有蓝色框的部分中看到的那样。
但是,如果您查看标记为红色的两个区域,则可以看到该对象实际存在的date。 而且,为了清除任何混淆,消息被放在收到的消息队列中的部分如下所示:
我正如你所看到的,我甚至试着做一个Thread.VolatileWrite来确保值被写入
message.Tag = buffer.Tag; Thread.VolatileWrite(ref message.Tag,buffer.Tag); if (message.Tag == null) { isNullLog.Add(message.Id); } // Queue into received messages lock (peer.ReceivedMessages) { peer.ReceivedMessages.Enqueue(message); }
上面的代码片段都发生在工作线程中,正如你所看到的,我将buffer.Tag拷贝到message.Tag ,我甚至设置了一些运行时检查,用于debugging,检查message.Tag为空值并添加如果是这样的话,则将id列表称为“isNullLog”。 当NullReferenceException在主线程中被抛出时,这个列表是空的。
你也看到我locking了peer.ReceivedMessages队列,并在设置了message.Tag字段之后将消息推送到队列中。
此外,更清楚的是用于从peer.ReceivedMessages队列中读取消息的peer.ReceivedMessages 。
public bool TryGetMessage(out TIncomingMessage message) { lock (ReceivedMessages) { if (ReceivedMessages.Count > 0) { message = ReceivedMessages.Dequeue(); return true; } } ReceivedMessageEvent.Reset(); message = null; return false; }
你可以看到,我甚至在我检查计数之前locking队列,如果不是空的,我设置out属性并返回true,否则返回false。
老实说,我完全难住,写了几个multithreading应用程序之前,从来没有遇到过这个。
稍微更新一下,我也试着将Tag字段Tag为volatile ,使得它看起来像这个public volatile object Tag; 但这似乎没有帮助。
如何将Windows服务从本地PC移动到虚拟专用服务器上
如何在特殊的PowerShell链命令4命令提示符?
检测HWND可见性更改
什么是Windows平台的GPS中间驱动程序的等效物?
我应该在哪里存储适用于非漫游用户的机器范围的应用程序设置?
我现在确实已经解决了这个问题,就像在处理线程时一样,在读取/写入值时需要格外小心。 我忘了清除接收循环中的本地message变量,并在下一次循环迭代中“重复使用”相同的消息,因为它有一个if(message == null) { /* create new message */ } check before每一次迭代,当我不清除这个线程时,读取线程结束了对尝试写入新消息时存储在这里的“旧”消息的践踏。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。