Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda expressions with multithreading in C#

I am trying to understand why this program doesn't work

Expected output: numbers 0-19 in random order What I get when I run: some numbers repeat, sometimes 20 is printed.

Please help. I tried with lock(obj) in DoSomething() but it didn't help.

Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    public delegate void callbackDelegate(int x);
    class Program
    {
        void processCallback(int x)
        {
            Console.WriteLine("IN callback: The value I got is " + x);
        }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.processinThreads();
            Console.ReadKey();
        }

        public void DoSomething(int x, callbackDelegate callback)
        {
            Thread.Sleep(1000);
            //Console.WriteLine("I just woke up now " + x);
            callback(x);
        }

        public void processinThreads()
        {
            for (int i = 0; i < 20; i++)
            {
                Thread t = 
new Thread(new ThreadStart(()=>DoSomething(i, processCallback)));
                t.Start();
            }
        }
    }
}
like image 397
satya Avatar asked Dec 03 '22 05:12

satya


2 Answers

public void processinThreads()
{
    for (int i = 0; i < 20; i++)
    {
        int local = i;
        Thread t = new Thread(new ThreadStart(()=>DoSomething(local, processCallback)));
        t.Start();
    }
}

Your problem is related to closure over lambda.

like image 118
Jakub Konecki Avatar answered Dec 29 '22 12:12

Jakub Konecki


You should just use the TPL, its a lot easier and recommended over manual thread management:

Parallel.For(0, 20, x => {
    Thread.Sleep(1000);
    Console.WriteLine("IN callback: The value I got is " + x);
});

This will also block until the loop finishes, if you don't want that you can use the TPL Task, but I would definitely recommend avoiding threads.

like image 22
Paul Tyng Avatar answered Dec 29 '22 12:12

Paul Tyng