0

I have to support a desktop application that had been implemented by another developer. The application has some 'magic' code, and TPL is not working after it is called.

I think that someone blocked ThreadPool from working but I have no idea how to find this. The question is: What going on in VeryLargeBlackBoxMethod() method? How do I find out what the the wrong code is?

    [STAThread]
    public static void Main()
    {
        var testTimer = new System.Threading.Timer((s) => { Console.WriteLine("This code never run"); });
        testTimer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

        PrintAvailableThreads();

        // ThreadPool can`t provide a new Task after this method executing
        VeryLargeBlackBoxMethod();

        PrintAvailableThreads();

        Task.Factory.StartNew(() => { Console.WriteLine("This code never run too"); });

        ThreadPool.QueueUserWorkItem((p) => { Console.WriteLine("And this code newer run"); });

        var thread = new Thread(() => { Console.WriteLine("But this code work"); });
        thread.Start();

        Console.ReadLine();
    }

    private static void PrintAvailableThreads()
    {  
        var work = 0;
        var completionThreads = 0;
        ThreadPool.GetAvailableThreads(out work, out completionThreads);
        Console.WriteLine("worker threads {0}, completionThreads {1}", work,         completionThreads);
    }

    // Console output:
    // worker threads 32767, completionThreads 1000
    // worker threads 32762, completionThreads 1000
    // But this code work
supertoha
  • 192
  • 1
  • 8
  • 3
    You could use something like a reflector, to see inside – Jeroen van Langen Apr 04 '17 at 13:45
  • 1
    Without looking inside the `VeryLargeBlackBoxMethod()` it's nearly impossible to find out what is going on. If you have access to the source code, I would check out if there are a number of long running tasks that should be moved to background threads. Tasks are _intended_ for short running code. – Berin Loritsch Apr 04 '17 at 13:45
  • starting a new Thread and using Task.Factory.StartNew (or Task.Run) are different – Alex Apr 04 '17 at 13:54
  • 2
    Out of interest, what does [`ThreadPool.GetMaxThreads`](https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads(v=vs.110).aspx) return? – stuartd Apr 04 '17 at 13:54
  • http://stackoverflow.com/questions/23216417/what-is-difference-between-task-factory-startnew-and-new-thread-start – Alex Apr 04 '17 at 13:56
  • @stuartd worker threads 32767, completionThreads 1000 The application works fine if I put ThreadPool.SetMinThreads(100, 100); before VeryLargeBlackBoxMethod(); But it's not a solution. – supertoha Apr 04 '17 at 14:05
  • What values does ThreadPool.GetAvailableThreads return? – Rodrigo Vedovato Apr 04 '17 at 14:13
  • @Rodrigo Vedovato, GetAvailableThreads: worker threads 32762, completionThreads 1000 – supertoha Apr 04 '17 at 14:17
  • 1
    That's a very huge amount of threads. They probably stuck fighting each over, so you're in a thread starvation situation. – VMAtm Apr 04 '17 at 15:54
  • @supertoha what are these numbers **before** the huge method? – VMAtm Apr 04 '17 at 19:01
  • 1
    @supertoha, run the application in the debugger. And pause the application (i.e. Break All, Ctrl+Alt+Break). Go to Debug -> Windows -> Threads, and look where the worker threads are stuck. I'm willing to bet there is a deadlock. – Ilian Apr 05 '17 at 07:30

0 Answers0