You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用With语句改写BeginInvoke委托代码触发空引用异常的原因咨询

为什么使用With语句改写后会抛出空引用异常?

这个问题我之前也碰到过,核心原因是VB.NET的With语句上下文不会被异步执行的匿名函数捕获,导致后续调用时找不到目标对象。

具体原因拆解:

  • 当你用With myGridView包裹代码时,这个With的上下文(也就是.指向的myGridView)只在当前同步执行的代码块内有效。
  • 但你把匿名Sub传给了BeginInvoke,这个Sub是异步执行的——它会被放到UI线程的消息队列里,等当前同步代码执行完后才会运行。
  • VB.NET的闭包机制不会把With的上下文对象(也就是myGridView)捕获到匿名函数里。当异步Sub真正执行时,原来的With上下文已经不存在了,这时候.就相当于在引用一个Nothing,自然就抛出空引用异常了。
  • 反观你的原代码,直接通过myGridView变量调用方法,这个变量会被闭包正常捕获,只要myGridView在异步执行时还未被销毁,就能正常访问。

修复方案:

你可以通过以下两种方式解决这个问题:

方案1:在With内部把目标对象存为局部变量

把myGridView赋值给一个局部变量,让闭包捕获这个变量,这样异步执行时就能正常访问:

With myGridView
    ' 把With的目标对象存为局部变量
    Dim targetGrid = .
    BeginInvoke(New Action(Sub()
                              Dim i As Integer = 0
                              Do While i < selectedRows.Count
                                  targetGrid.SelectRow(targetGrid.GetRowHandle(selectedRows(i)))
                                  i += 1
                              Loop
                          End Sub))
End With

方案2:直接在匿名函数里引用原变量

放弃在异步函数里使用With的.,直接用myGridView调用方法,和你的原代码逻辑保持一致:

With myGridView
    BeginInvoke(New Action(Sub()
                              Dim i As Integer = 0
                              Do While i < selectedRows.Count
                                  myGridView.SelectRow(myGridView.GetRowHandle(selectedRows(i)))
                                  i += 1
                              Loop
                          End Sub))
End With

内容的提问来源于stack exchange,提问作者Nidx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:29:53