7

我的应用程序中有一个错误,似乎只有当我在调试器中暂停应用程序几分钟时才会显示它的面孔。我怀疑这是由于我使用的第三方网络库有一个心跳线程,当它的心跳线程暂停时它无法 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!
4

5 回答 5

4

您可以使用它来快速识别进程的线程:

using System.Diagnostics;

ProcessThreadCollection threads = Process.GetCurrentProcess().Threads;

然后,您可以使用带有 P/Invoke 的 kernel32.dll来对这些线程执行任何您需要的操作。使用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);
于 2010-11-10T12:42:25.677 回答
1

我假设您不会暂停应用程序中的所有线程,否则将不会运行任何东西来取消暂停它们。还是我错过了什么?

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

于 2010-11-10T12:51:53.817 回答
1

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

  • 您正在编写哪种测试?如果您在谈论单元测试,那么这不是单元测试用例 - 听起来更像是集成测试
  • 考虑隔离类中的 API 调用,然后使用依赖注入,这样您就可以在没有 3rd 方库的情况下使用 mocks/stub 进行测试,也可以引发/测试从 3rd 方库引发的异常
于 2010-11-10T13:06:35.653 回答
1

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

Jon Skeet 认为您无法在普通 C# 代码中枚举托管线程,尽管他确实暗示了一个可能的解决方案。

于 2010-11-10T12:45:07.533 回答
0

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

但您可以执行以下操作: 设置一个布尔标志,设置后您的线程将进入大睡眠状态。或者更好地使用ManualResetEvent

于 2010-11-10T12:43:14.803 回答