1

2 つのアプリケーション間の相互作用に少し問題があります。

次のようなコードで問題を再現できます。

using (Form1 frm = new Form1())
{
    frm.ShowDialog();
}

Thread.Sleep(120000);

このコードを使用すると、アプリケーションがコードの一部を実行しているときに、制御していない別のアプリケーションがフリーズしThread.Sleepます。以前にこのバグの受信側にいたので、実際に何が起こっているのかについてはよくわかっています。他のアプリにはEnumWindows、IsWindowVisible ネイティブ メソッドを使用してウィンドウが表示されているかどうかを確認しないネイティブ メソッドからのコールバックがあります。次に、他の関数を呼び出すGetWindowTextか、他の関数を呼び出すと、ハングします。

このハングの理由は、まだハンドルが登録されている (現在は閉じられている) ウィンドウと通信しようとしているためですが、そのキューに送信されたメッセージに応答しないため、呼び出し元は無期限にそこに座っているだけです ( Window は Thread.Sleep の後に完全に終了します)。

これは、対処しなければならない「アンタッチャブル」アプリケーションのサンプル コードです。

public bool RunTest()
{
    return NativeMethods.EnumWindows(new NativeMethods.EnumWindowsProc(EnumWindowsCallback), IntPtr.Zero);
}

private bool EnumWindowsCallback(IntPtr windowHandle, IntPtr parameter)
{
    NativeMethods.SendMessage(windowHandle, 0x000E, IntPtr.Zero, IntPtr.Zero);
    return true;
}

最初のコードを実行し、開いたウィンドウを閉じてから、別のプロセスで 2 番目のコード ブロックを実行すると、2 番目の (EnumWindows) プロセスがハングします。

私の問題は、これに対処しなければならず、ハングしているアプリケーションのコードを修正するだけでは済まないことです。ウィンドウを別のスレッドで開始することはできますが、それは不器用でやや壊れやすいようです。ネイティブ呼び出しまたはその他のより直接的な方法を使用してこの問題を解決する方法を知っている人はいますか?

4

1 に答える 1

1

呼び出す代わりに、Sleep(関数で作成された)待機可能なタイマーを使用し、タイマーが切れるまでCreateWaitableTimer(関数を使用して)メッセージループを実行し続けることができます。MsgWaitForMultipleObjects

于 2013-03-13T19:45:31.273 に答える