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

.Net中如何在线程调用中传递ByRef参数或获取对应读写委托

问题根因

.NET 内置的Action(Of T)、Func(Of TResult)等泛型委托的参数默认都是按值传递,不支持ByRef修饰的参数,所以你定义的Sub(ByRef t As MyType)无法匹配Action(Of MyType)的签名。同时Thread.Start方法的参数是Object类型,传递值类型时只会生成副本,无法直接实现按引用修改的效果。


解决方案

方案1:用引用类型包装值类型(推荐)

值类型继承自Structure,默认按值传递,我们可以用一个引用类型的包装类承载值,传递包装类的引用就等价于实现了按引用操作原始值的效果,全程可以用标准的内置委托,兼容性最好。
首先定义通用包装类:

Public Class ValueWrapper(Of T As Structure)
    Public Property Value As T
End Class

改造后的业务代码:

Public Sub UseLater(Of T As Structure)(wrapper As ValueWrapper(Of T), m As Mutex, callback As Action(Of T))
    m.WaitOne()
    Try
        callback(wrapper.Value)
    Finally
        m.ReleaseMutex()
    End Try
End Sub

'' 调用侧代码
Dim getterLock As New Mutex()
Dim buffer As MyType = Nothing
' 包装要传递的原始值
Dim objWrapper As New ValueWrapper(Of MyType) With {.Value = MyObject}

Dim threadhelper As Action = Sub()
                               UseLater(Of MyType)(objWrapper, getterLock, Sub(t) buffer = t)
                             End Sub

getterLock.WaitOne()
Dim getLater As New Thread(threadhelper)
getLater.Start()
Dim getter As Func(Of MyType) = Function()
                                   getterLock.ReleaseMutex()
                                   Return buffer
                                 End Function

方案2:自定义支持ByRef的委托

如果你确实需要保留ByRef参数的写法,可以自定义匹配签名的委托类型,配合闭包捕获要传递的变量即可:
首先自定义委托:

' 声明支持ByRef参数的自定义委托
Public Delegate Sub ByRefAction(Of T As Structure)(ByRef t As T)

改造后的业务代码:

Public Sub UseLater(Of T As Structure)(ByRef t As T, m As Mutex, callback As ByRefAction(Of T))
    m.WaitOne()
    Try
        callback(t)
    Finally
        m.ReleaseMutex()
    End Try
End Sub

'' 调用侧代码
Dim getterLock As New Mutex()
Dim buffer As MyType = Nothing
Dim target As MyType = MyObject ' 要传递的原始变量

' 闭包直接捕获target变量,无需通过Thread.Start传参
Dim threadhelper As ThreadStart = Sub()
                                    UseLater(Of MyType)(target, getterLock, Sub(ByRef t_) buffer = t_)
                                  End Sub

getterLock.WaitOne()
Dim getLater As New Thread(threadhelper)
getLater.Start()
Dim getter As Func(Of MyType) = Function()
                                   getterLock.ReleaseMutex()
                                   Return buffer
                                 End Function

方案选型建议

  • 跨方法、跨作用域传递参数时优先选方案1,符合.NET常规编码规范,逻辑更易维护
  • 小范围临时使用时可以选方案2,代码更轻量化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:06:04