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

时间:2015-02-19 15:36:06

标签: c# vb.net multithreading asynchronous c#-to-vb.net

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

我从这篇文章中得到了想法:Wait for pooled threads to complete

我有兴趣在没有WaitHandle的情况下尝试JaredPar的答案(因为它有64个线程限制),但我不知道如何复制他的QueueUserWorkItem in这个VB应用程序:

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);
}

如何用VB编写x => wrappedAction()

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

下面是我写的一个小小的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. 类型的价值&#39; System.Action&#39;无法转换为&#39; System.Threading.WaitCallback&#39;
  4. 这个项目编译成.NET 4.0,所以我不能真正使用4.5等待功能,除非插件被授权用于公司项目。

3 个答案:

答案 0 :(得分:4)

  

x =&gt; wrappedAction()是用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

答案 1 :(得分:2)

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())

答案 2 :(得分:0)

获取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