VB.NET中跨线程访问ConcurrentBag触发空引用异常如何解决?
问题根因
你遇到的NullReferenceException主要来自两个原因:
- VB.NET的默认窗体实例是线程绑定的,
Form1.conc这种访问方式在子线程中不会获取到UI线程创建的Form1实例,会返回Nothing,直接访问成员就会抛空引用 SingleOrDefault方法找不到匹配的Item对象时会返回Nothing,直接调用.Value属性也会触发空引用
可行解决方案
最稳妥的方式是避免跨线程访问窗体实例,直接把集合对象作为参数传入业务方法,降低耦合:
- 修改
SeekerMeeker类的GetValue方法,接收集合参数并增加空判断:
Public Class SeekerMeeker Public Function GetValue(conc As Concurrent.ConcurrentBag(Of Item), val As Integer) As Integer Dim target = conc.SingleOrDefault(Function(t) t.Value = val) ' 空值判断避免空引用 If target Is Nothing Then ' 可根据业务需求调整默认返回值或抛出自定义异常 Return -1 End If Return target.Value End Function End Class
- 修改
Leker方法,直接传入当前窗体的conc集合,不需要访问默认Form1实例:
Private Sub Leker() Dim d As New SeekerMeeker Dim result = d.GetValue(conc, 1) ' 跨线程更新UI需要用Invoke切回UI线程,避免跨线程操作异常 Me.Invoke(Sub() MsgBox(result)) End Sub
额外优化建议
- 可以在填充集合的
Feltolt方法执行完成前,禁用按钮点击,避免用户在集合未填充完成时查询不到数据 - 如果你确实需要在多处访问窗体实例,可在程序启动时将UI线程的Form1实例存储到全局变量,不要用默认的
Form1语法糖访问
内容的提问来源于stack exchange,提问作者Mesos
相关产品推荐
相关产品推荐

