Home > Blockchain >  Receiving unexpected output while implementing multithreading in c#
Receiving unexpected output while implementing multithreading in c#

Time:11-06

I am new to c# and multithreading concept and was exploring multithreading. I am getting unexpected output. Following is the program I wrote in c#:-

static void Main(string[] args)
        {

            for (int i = 1; i <= 5; i  )
            {
                
                System.Threading.Thread workerThread = new System.Threading.Thread(() => fn(i));
                workerThread.Start();
                
            }

            System.Console.WriteLine("!End the main process!");

        }
        public static void fn(int x)
        {
            System.Console.WriteLine($"fn method called for {x}");
            System.Threading.Thread.Sleep(5000);
            for (int i = 1; i <=2 ; i  )
            {
                System.Console.Write($" {x} ");
            }
        }

Expected Output:- One of the expected output would have been:-

  • !End the main process!
  • fn method called for 1
  • fn method called for 2
  • fn method called for 3
  • fn method called for 4
  • fn method called for 5
  • 1 1 2 2 3 3 4 4 5 5

Actual Output what I am getting is:-

  • !End the main process!
  • fn method called for 4
  • fn method called for 3
  • fn method called for 2
  • fn method called for 5
  • fn method called for 2
  • 2 2 2 4 2 4 3 3 5 5

Why the function fn was called twice of 2 and why it wasn't called for 1?

and when I re-run the function I am getting

  • !End the main process!
  • fn method called for 3
  • fn method called for 4
  • fn method called for 3
  • fn method called for 6
  • fn method called for 4
  • 3 3 3 3 4 4 6 4 6 4

How did fn end up getting called for 6?

CodePudding user response:

Because you are passing i as an argument, it depends on what the value of i is at the specific moment the method is executed. If the method doesn't get executed until your loop has moved on to the next iteration, it will get the incremented value of i.

The solution is to not use a variable that has that outer scope. Declare a local variable specifically for the method argument:

for (int i = 1; i <= 5; i  )
{
    var arg = i;

    System.Threading.Thread workerThread = new System.Threading.Thread(() => fn(arg));
    workerThread.Start();    
}

arg is allocated anew for each iteration so every method call will get the correct value of arg.

  • Related