在运行时暂停当前进程中的所有线程

时间:2010-11-10 12:38:48

标签: c# .net multithreading heartbeat tibco-ems

我的应用中有一个错误,只有当我在调试器中暂停应用程序几分钟时才会显示它的面孔。我怀疑这是由于我使用的第三方网络库有一个心跳线程,当它的心跳线程暂停时它无法ping服务器时会断开连接。

我正在尝试为此编写测试用例应用程序,以验证这是导致错误的原因。为此,我需要一种方法来暂停应用程序中的所有线程(稍后我将缩小到仅暂停我怀疑可能是心跳线程的线程)来模拟在调试器中暂停应用程序。

有谁知道怎么做?一个线程甚至可能导致另一个线程睡眠吗?

谢谢, 亚历

更新:

我最终决定我并不真的需要一个应用程序来为我这样做,因为重点是验证调试器中的暂停导致断开连接。所以,这就是我所做的......(最简单的方法往往是最好的......或者至少是最简单的......)

    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();
    }

输出:

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!

5 个答案:

答案 0 :(得分:4)

您可以使用它来快速识别流程的主题:

using System.Diagnostics;

ProcessThreadCollection threads = Process.GetCurrentProcess().Threads;

然后你可以use kernel32.dll with P/Invoke用这些线程做你需要的任何事情。使用OpenThread获取所需线程的句柄,然后使用该句柄使用SuspendThread暂停它。

以下是两种方法的P / Invoke声明:

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

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

答案 1 :(得分:1)

您可以通过调用Thread.Suspend来暂停线程。文档给出了很大的“不要这样做!”弃用警告,但我认为您的用例是有效的用例。

Jon Skeet在正常的C#代码中认为you can't enumerate managed threads,尽管他暗示了可能的解决方案。

答案 2 :(得分:1)

我假设您不会暂停所有应用程序中的线程,否则将无法运行以取消暂停它们。或者我错过了什么?

建议:尝试为您创建的所有主题指定名称。任何没有名称或与命名约定不匹配的线程必须由第三方组件创建。这可能会让您更快地找到根本原因而无需暂停大量线程。

答案 3 :(得分:1)

从我的pov来看,这听起来不对。

  • 你在写什么样的考试?如果你在谈论单元测试,那么这不是一个单元测试案例 - 听起来更像集成测试
  • 考虑隔离类中的API调用,然后使用dependendcy注入,以便您可以在没有带有模拟/存根的第三方库的情况下进行测试,并且还可以激发/测试从第三方库引发的异常

答案 4 :(得分:0)

您可以调用Thread.Suspend然后Thread.Resume方法,但这些方法已弃用,不建议使用它们。

但您可以执行以下操作: 有一个布尔标志,设置时让你的线程处于大睡眠状态。 要么 最好使用ManualResetEvent

相关问题