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;

次に、kernel32.dllをP / Invokeとともに使用して、これらのスレッドで必要なことをすべて実行できます。OpenThreadを使用して目的のスレッドへのハンドルを取得し、そのハンドルを使用してSuspendThreadでサスペンドします。

2つのメソッドの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

を呼び出すことにより、スレッドを一時停止できますThread.Suspend。ドキュメントには大きな「これをしないでください!」が記載されています。非推奨の警告ですが、あなたの使用例は有効だと思います。

Jon Skeetは、通常のC#コードではマネージスレッドを列挙できないと考えていますが、考えられる解決策を示唆しています。

于 2010-11-10T12:45:07.533 に答える
1

アプリケーション内のすべてのスレッドを一時停止するつもりはないと思います。そうしないと、一時停止を解除するために何も実行されません。それとも私は何かを逃したことがありますか?

提案:作成するすべてのスレッドに名前を付けてみてください。名前のないスレッド、または命名規則に一致しないスレッドは、サードパーティのコンポーネントによって作成されている必要があります。これにより、多くのスレッドを一時停止することなく、根本的な原因にすばやく到達できる可能性があります。

于 2010-11-10T12:51:53.817 に答える
1

私のハメ撮りから、これは正しくないように聞こえます。

  • どのようなテストを書いていますか?単体テストについて話している場合、これは単体テストケースではありません-統合テストのように聞こえます
  • クラス内のAPI呼び出しを分離してから、依存関係インジェクションを使用することを検討してください。これにより、モック/スタブを使用してサードパーティライブラリなしでテストでき、サードパーティライブラリから発生した例外を誘発/テストすることもできます。
于 2010-11-10T13:06:35.653 に答える
0

Thread.Suspendthenメソッドを呼び出すこともできますThread.Resumeが、これらは非推奨であり、使用することはお勧めしません。

ただし、次のことができます。設定時にスレッドを大きなスリープ状態にするブールフラグを設定します。またはManualResetEventを使用することをお勧めします。

于 2010-11-10T12:43:14.803 に答える