Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

231
Views
Thread.Join method does not always return the same value when the thread has already terminated (.NET 5 / Core)

The Thread.Join method has three overloads: Join(), Join(Int32) and Join(TimeSpan). For each of these three overloads, there is the following statement in the Microsoft doc:

If the thread has already terminated when Join is called, the method returns immediately.

While this statement makes sense for the Join() overload, it doesn't specify which value is returned for the Join(Int32) and Join(TimeSpan) ones, so I tested the Int32 overload in two different environments:

  1. Windows 10: return true
  2. Linux/Docker: return false (using mcr.microsoft.com/dotnet/runtime:5.0 on Docker Desktop)

Note that the Linux/Docker implementation is returning true (like the Windows one) if the thread is still running when Join is called and has terminated after the call. It only returns false if the thread has terminated before the call.

In my opinion Join should always return true whatever the platform, so what could explain this inconsistent behavior? Am I missing something or is it a .NET 5 bug?

UPDATE

As suggested by @txtechhelp, here is a .NET Fiddle with the exact code I'm testing.

If I run this code on Windows 10 (or in .NET Fiddle) I get the following result:

Starting..
Sleeping 1200..expect T1 end before join
In T1
Leaving T1
Join(100)..expect success
Join(100) success!
Done..

Then if I run this code using mcr.microsoft.com/dotnet/runtime:5.0 on Docker Desktop (v. 3.1.0) then I get the following result:

Starting..
Sleeping 1200..expect T1 end before join
In T1
Leaving T1
Join(100)..expect success
Join(100) failed
Done..

UPDATE 2

Actually after further testing I realized that the test above is only failing if I call the Join when the Docker application is unloading (i.e. after receiving the AssemblyLoadContext.Default.Unloading event, which is the signal sent by Docker to inform that it's going to shutdown the application).

So here is the exact test which is even failing on .NET Fiddle:

public class Program
{
    public static void Main()
    {
        System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (arg) => { OnStopSignalReceived("application unloading"); };
    }

    public static void T1()
    {
        System.Console.WriteLine("In T1");
        System.Threading.Thread.Sleep(1000);
        System.Console.WriteLine("Leaving T1");
    }

    private static void OnStopSignalReceived(string stopSignalSource)
    {
        System.Threading.Thread t1 = new System.Threading.Thread(T1);
        System.Console.WriteLine("Starting..");
        t1.Start();
        System.Console.WriteLine("Sleeping 1200..expect T1 end before join");
        System.Threading.Thread.Sleep(1200);
        System.Console.WriteLine("Join(100)..expect success");
        if (t1.Join(100))
        {
            System.Console.WriteLine("Join(100) success!");
        }
        else
        {
            System.Console.WriteLine("Join(100) failed");
        }
        t1.Join();
        System.Console.WriteLine("Done..");
    }
}
over 4 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!