如何在 VB 中编写此匿名 C# 方法?

How to write this Anonymous C# method in VB?

我需要为 ThreadPool 生成多个后台线程(我的测试商店包含 6008 个部件号,各个线程将从公司数据库中查找每个部件的条形码和描述)。

我从这个 post 中获得灵感:Wait for pooled threads to complete

我有兴趣在这个 VB 应用程序中尝试 JaredPar's answer without the WaitHandle (since it has a 64 thread limit), but I don't know how to duplicate his QueueUserWorkItem

public static void SpawnAndWait(IEnumerable<Action> actions)
{
    var list = actions.ToList();
    var handles = new ManualResetEvent[actions.Count()];
    for (var i = 0; i < list.Count; i++)
    {
        handles[i] = new ManualResetEvent(false);
        var currentAction = list[i];
        var currentHandle = handles[i];
        Action wrappedAction = () => { try { currentAction(); } finally { currentHandle.Set(); } };
        ThreadPool.QueueUserWorkItem(x => wrappedAction());
    }
    WaitHandle.WaitAll(handles);
}

x => wrappedAction()怎么写成VB?

这似乎是一个简单的任务,但我找不到任何关于如何转换它的信息。

下面是我写的一个小 VB 存根,试图让它工作。

使用某人在 Invoke anonymous methods 中找到的内容,我尝试以不同的方式编写它。

Private m_db As DatabaseHelper

Public Sub Test1(store As StoreLocation)
    For index As Integer = 0 To store.Parts.Count - 1
        Dim item As StorePart = store.Parts(index)
        Dim job As New Action(
            Sub()
              Dim lines As String() = m_db.GetDetails(store.ID, item.PartNumber)
              item.UPC = lines(0)
              item.Vendor = lines(1)
              item.Description = lines(2)
            End Sub
        )
        ThreadPool.QueueUserWorkItem(job()) ' See 1.
        ThreadPool.QueueUserWorkItem(job.Invoke()) ' See 2.
        ThreadPool.QueueUserWorkItem(job) ' See 3.
    Next
End Sub

不,它不编译。

  1. 表达式不产生值
  2. 表达式不产生值
  3. 类型 'System.Action' 的值无法转换为 'System.Threading.WaitCallback'

此项目编译为 .NET 4.0,因此我无法真正使用 4.5 await 功能,除非已为公司项目授权插件。

How would x => wrappedAction() be written in VB?

Well it is 

Sub(x) wrappedAction()

尽管 x 无关紧要,因为它未被使用,因此您可以使用 Sub() wrappedAction() 代替

所以应该这样做:

Public Shared Sub SpawnAndWait(ByVal actions As IEnumerable(Of Action))
    Dim list = actions.ToList()
    Dim [handles] = New ManualResetEvent(actions.Count() - 1){}
    For i = 0 To list.Count - 1
        [handles](i) = New ManualResetEvent(False)
        Dim currentAction = list(i)
        Dim currentHandle = [handles](i)
        Dim wrappedAction As Action = Sub()
            Try
                currentAction()
            Finally
                currentHandle.Set()
            End Try
        End Sub
        ThreadPool.QueueUserWorkItem(Sub(x) wrappedAction())
    Next i
    WaitHandle.WaitAll([handles])
End Sub

WaitCallback 委托定义为

<ComVisibleAttribute(True)> _
Public Delegate Sub WaitCallback(state As Object)

所以正确的语法是:

ThreadPool.QueueUserWorkItem(Sub(state As Object) wrappedAction())

ThreadPool.QueueUserWorkItem(Sub(state As Object) job())
ThreadPool.QueueUserWorkItem(Sub(state As Object) job.Invoke())
ThreadPool.QueueUserWorkItem(Sub(state As Object) job())

获取 C# 代码,对其进行编译,然后通过 JustDecompile 运行 汇编并选择 VB 作为输出语言,我得到:

Public Shared Sub SpawnAndWait(ByVal actions As IEnumerable(Of System.Action))
    Dim list As List(Of System.Action) = actions.ToList(Of System.Action)()
    Dim handles(actions.Count(Of System.Action)()) As System.Threading.ManualResetEvent
    Dim i As Integer = 0
    While i < list.Count
        handles(i) = New System.Threading.ManualResetEvent(False)
        Dim item As System.Action = list(i)
        Dim manualResetEvent As System.Threading.ManualResetEvent = handles(i)
        Dim action As System.Action = Sub()
        Try
            item()
        Finally
            manualResetEvent.[Set]()
        End Try
        End Sub
        ThreadPool.QueueUserWorkItem(Sub(x As Object) action())
        i = i + 1
    End While
    WaitHandle.WaitAll(handles)
End Sub