2

I am trying change from Delegates to Parallel.ForEach

I see the below works fine.

Imports System.Threading.Tasks

  Sub Main()
   Dim secs() As Integer = {2, 3, 1}
   Parallel.ForEach(secs, AddressOf Method2)
  End Sub

  Sub Method2(ByVal i As Integer)
   Console.WriteLine(i.ToString)
  End Sub

But what if my Sub takes more then one variable? Can you show me how I should do the below?

Imports System.Threading.Tasks
  Sub Main()
   Dim secs() As Integer = {2, 3, 1}
   Dim Path as String = "Constant"

   Parallel.ForEach(secs, Path, AddressOf Method2)
  End Sub

 Sub Method2(ByVal i As Integer, path as string )
  Console.WriteLine(i.ToString, path)
 End Sub

Thank you

Jasin
  • 425
  • 1
  • 6
  • 17

2 Answers2

4

You can do this via a Lambda Expression:

Imports System.Threading.Tasks
  Sub Main()
   Dim secs() As Integer = {2, 3, 1}
   Dim Path as String = "Constant"

   Parallel.ForEach(secs, Sub(sec) Method2(sec, Path))
  End Sub

 Sub Method2(ByVal i As Integer, path as string)
  Console.WriteLine(i.ToString(), path)
 End Sub

This will allow the compiler to create a closure that gets the value of Path, and pass it directly into your method.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Thanks, I can't add an answer yet for 3 more minutes. But I do get that same warning with Sub – Jasin Nov 05 '11 at 00:58
  • @Jasin Is that warning a Visual Studio warning, or a Resharper/3rd party tool warning? I suspect it's a false warning... – Reed Copsey Nov 05 '11 at 01:00
  • VS 2010 Pro, I will be happy to ignore it, just making sure. – Jasin Nov 05 '11 at 01:02
  • @Jasin The code I have above, exactly as typed, doesn't give that warning in Visual Studio 2010... (And it works correctly). Do you have Resharper or any extensions installed? – Reed Copsey Nov 05 '11 at 01:03
  • Productivity Power Tools, Spell Checker. - Perhaps do you think It matters that Path is actually from a ForEach in Paths? - My code is more complex then above, was just trying to get this part right. – Jasin Nov 05 '11 at 01:06
  • @Jasin: If you want to edit your question or ask another question - post your actual code. It may matter ,depending on what you're doing... Is this entire thing in a foreach? – Reed Copsey Nov 05 '11 at 01:07
  • @Jasin: I'd recommend taking your current code, and making a question showing the warning/error and asking why it's causing it (now that this part is fixed) – Reed Copsey Nov 05 '11 at 01:08
1

Certainly in C#, I'd use a lambda expression to call Method2 instead:

Parallel.ForEach(secs, i => Method2(i, path));

Whether the equivalent will look elegant in VB is beyond the amount of good judgement I have about a language I don't use at 12.50am, but you don't have a lot of other choices really - assuming you don't want to create an instance of another class, passing path into the constructor, and then using a single-parameter method in that class...

(Oh, and another option would be to change Method2 into a single parameter method where the parameter encapsulated both values. So I guess you do have a few options - but in C# at least, the lambda expression one would be the way to go.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I converted this to Parallel.ForEach(Directories, Function(i) ScanDirectory(i, Path)) and get this warning (Using the iteration variable in a lambda expression may have unexpected results. Instead, create a local variable within the loop and assign it the value of the iteration variable.) Thoughts? – Jasin Nov 05 '11 at 00:54
  • @Jasin My answer shows the correct syntax for this in VB - you need `Sub(i)`, not `Function(i)` – Reed Copsey Nov 05 '11 at 00:55