0

I have a problem with System.Threading.Tasks, I don't understand why it doesn't works.

Dim table_sec As New Dictionary(Of String, List(Of Double))

table_sec.Add("SEC01", New List(Of Double)(New Double() {10.00, 5.00}))
table_sec.Add("SEC02", New List(Of Double)(New Double() {9.00, 8.00}))
table_sec.Add("SEC03", New List(Of Double)(New Double() {5.00, 2.00}))

    Dim pair As KeyValuePair(Of String, List(Of Double))
    Dim tasks As New List(Of Task)()

    For Each pair In table_sec
    Dim t As Task = Task.Run(Sub()
    Console.WriteLine("Key = " & pair.Key)
                   End Sub)

    tasks.Add(t)

    Next     

   Task.WaitAll(tasks.ToArray())

I always get this result

Key = SEC03
Key = SEC03
Key = SEC03

Can you tell me what is wrong ?

Mkn
  • 498
  • 1
  • 3
  • 13
  • I'm not sure but `pair.Key` in the task sub might be a reference to the last pair in the list when the task is executed. When you print `pair.Key` in the for each loop outside of the task it should show all three values I guess? – xander Nov 29 '17 at 09:54
  • yes , outside of the 'Task' it shows the 3 values – Mkn Nov 29 '17 at 09:57
  • 2
    I think [this](https://stackoverflow.com/questions/451779/how-to-tell-a-lambda-function-to-capture-a-copy-instead-of-a-reference-in-c) might help you, because you capture an outside variable in your sub, it can get a little confusing. :D – xander Nov 29 '17 at 09:58
  • I know you've shown me how to do it with your link but...Can you please show me a simple example – Mkn Nov 29 '17 at 10:22
  • It's ok , I understand , sorry ,thanks for the link – Mkn Nov 29 '17 at 10:43
  • I just posted an answer, I think that might help but I cannot test it. – xander Nov 29 '17 at 10:45

1 Answers1

0

I haven't used VB.Net in years and I can't test it, but you might try and follow the simple example of my suggested link and use a local copy of the captured reference:

Dim table_sec As New Dictionary(Of String, List(Of Double))

table_sec.Add("SEC01", New List(Of Double)(New Double() {10.00, 5.00}))
table_sec.Add("SEC02", New List(Of Double)(New Double() {9.00, 8.00}))
table_sec.Add("SEC03", New List(Of Double)(New Double() {5.00, 2.00}))

Dim pair As KeyValuePair(Of String, List(Of Double))
Dim tasks As New List(Of Task)()

For Each pair In table_sec
  Dim p As KeyValuePair(Of String, List(Of Double))
  p = pair ' make a copy to the actual pair in this loop iteration
  Dim t As Task = Task.Run(Sub()
  Console.WriteLine("Key = " & p.Key) ' capture local copy p instead of pair
               End Sub)

  tasks.Add(t)

Next     

Task.WaitAll(tasks.ToArray())
xander
  • 1,780
  • 9
  • 16