如何在 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
不,它不编译。
- 表达式不产生值
- 表达式不产生值
- 类型 '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
我需要为 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
不,它不编译。
- 表达式不产生值
- 表达式不产生值
- 类型 '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