Pausing all threads in current process at run time

AlexC picture AlexC · Nov 10, 2010 · Viewed 7k times · Source

I have a bug in my app that seems to show it's face only when I pause the app in the debugger for a few minutes. I suspect this is due to a third party networking library I am using having a heartbeat thread, which becomes disconnected when it can not ping the server while it's heartbeat thread is paused.

I am trying to write a test case app for this to verify that this is the cause of the bug. To do so, I need a way to pause all the threads in the app (which i will later narrow down to pausing only the thread I suspect may be the heartbeat thread) to simulate pausing the app in the debugger.

Does anyone know how to do this? Is it even possible for one thread to cause another to sleep?

Thanks, Alex

UPDATE:

I ended up deciding that I didn't really need an app to do this for me, seeing as the point was just to verify that pausing in the debugger was causing the disconnect. So, here's what I did... (The simplest ways are often the best... or at least the simplest...)

    private static void Main(string[] args)
    {
        IPubSubAdapter adapter = BuildAdapter();
        bool waitingForMessage;
        adapter.Subscribe(_topic, message => waitingForMessage = false, DestinationType.Topic);
        Stopwatch timePaused = new Stopwatch();
        while (adapter.IsConnected)
        {
            Console.WriteLine("Adapter is still connected");
            waitingForMessage = true;
            adapter.Publish(_topic, "testmessage", DestinationType.Topic);
            while (waitingForMessage)
            {
                Thread.Sleep(100);
            }
            timePaused.Reset();
            timePaused.Start();
            Debugger.Break();
            timePaused.Stop();
            Console.WriteLine("Paused for " + timePaused.ElapsedMilliseconds + "ms.");
            Thread.Sleep(5000); // Give it a chance to realise it's disconnected.
        }
        Console.WriteLine("Adapter is disconnected!");
        Console.ReadLine();
    }

And the output:

Adapter is still connected
Paused for 10725ms.
Adapter is still connected
Paused for 13298ms.
Adapter is still connected
Paused for 32005ms.
Adapter is still connected
Paused for 59268ms.
Adapter is disconnected!

Answer

bitbonk picture bitbonk · Nov 10, 2010

You can use this to quickly indentify the threads of your process:

using System.Diagnostics;

ProcessThreadCollection threads = Process.GetCurrentProcess().Threads;

Then you can use kernel32.dll with P/Invoke to do whatever you need with those threads. Use OpenThread to get a handle to the desired thread and then suspend it with SuspendThread using that handle.

Here are the P/Invoke declaration for the two methods:

[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);

[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);