2017-04-04 4 views
2

私のWindowsフォームアプリケーションでは、アイテムの1つがクリックされた場合、特定のフォルダで新しいエクスプローラウィンドウを開く必要があります。 (私はすでに私はクリック座標を必要のあるいくつかのヒット検出を持っているので)私は私がProcess.Start()を使用するとWindowsForm MouseUpが2回発生する

private void listView1_MouseUp(object sender, MouseEventArgs e) 
    { 
     Process.Start(@"C:\"); 
    } 

によって新しいエクスプローラウィンドウを開くと、今では二回エクスプローラウィンドウを開きますMouseUpイベントをリッスンしています。これは、Process.Start(@"C:\");とはっきりと関係があります。なぜなら、通常のコンソール出力に回線を切り替えると、ただ1回実行されるだけなのでです。

すでに処理されているイベントをマークする方法はありますか、または2回目の実行を無視するだけですか?

+0

コードをステップ実行してコードを2回実行するかどうかを確認します。 –

+0

こんにちはバリC、ちょうどそれを試みた。私はちょうどConsole.WriteLine(e.Button)がある場合。私は出力を2回取得します。メソッドの中にブレークポイントを設定した場合は、一度だけ実行されます。多分、焦点は新しく開かれたエクスプローラウィンドウにシフトし、本当に速く戻るでしょうか?しかしそれはただの推測です。 – MatzeBrei

+0

うーん、奇妙な。 MouseUpではなく、MouseClickイベントを使ってみましたか? –

答えて

5

これはの再入荷バグで、DoEvents()をコードで使用したときのバグとよく似ています。しかし、この場合、バグはOSに組み込まれています。この問題のインストゥルメンタルはエクスプローラです。このコードでは非常に珍しい起動モードがあります。あなたがProcess.Start()の戻り値を見るときに見ることができるものは、nullです。 Process.Start()が実際にプロセスを開始しないときに発生します。

2回目のヒットになる条件付きブレークポイントを使用すると、動作中のバグを確認できます。管理対象外のデバッグおよびシンボルサーバーを有効にすると、コールスタックは、次のようになります。

WindowsFormsApp1.exe!WindowsFormsApp1.Form1.listView1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) Line 19 C# 
System.Windows.Forms.dll!System.Windows.Forms.Control.OnMouseUp(System.Windows.Forms.MouseEventArgs e) Line 9140 C# 
System.Windows.Forms.dll!System.Windows.Forms.ListView.WndProc(ref System.Windows.Forms.Message m) Line 6298 C# 
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Line 14236 C# 
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Line 14291 C# 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Line 780 C# 
[Native to Managed Transition] 
[email protected]() Unknown 
user32.dll!UserCallWinProcCheckWow() Unknown 
user32.dll!CallWindowProcW() Unknown 
[email protected]() Unknown 
[email protected]() Unknown 
[email protected]() Unknown 
[email protected]() Unknown 
user32.dll!UserCallWinProcCheckWow() Unknown 
user32.dll!DispatchMessageWorker() Unknown 
[email protected]() Unknown 
shell32.dll!SHProcessMessagesUntilEventsEx(struct HWND__ *,void * *,unsigned long,unsigned long,unsigned long,unsigned long) Unknown 
shell32.dll!CShellExecute::_RunThreadMaybeWait(bool) Unknown 
shell32.dll!CShellExecute::ExecuteNormal(struct _SHELLEXECUTEINFOW *) Unknown 
shell32.dll!ShellExecuteNormal(struct _SHELLEXECUTEINFOW *) Unknown 
[email protected]() Unknown 
System.ni.dll!71db9903() Unknown 
[Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack] 
[Managed to Native Transition] 
System.dll!System.Diagnostics.ShellExecuteHelper.ShellExecuteFunction() Unknown 
System.dll!System.Diagnostics.ShellExecuteHelper.ShellExecuteOnSTAThread() Unknown 
System.dll!System.Diagnostics.Process.StartWithShellExecuteEx(System.Diagnostics.ProcessStartInfo startInfo) Unknown 
System.dll!System.Diagnostics.Process.Start() Unknown 
System.dll!System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo startInfo) Unknown 
System.dll!System.Diagnostics.Process.Start(string fileName) Unknown 
WindowsFormsApp1.exe!WindowsFormsApp1.Form1.listView1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) Line 19 C# 

それは、「DoEvents関数」を綴るには長い道のり悪行為者であるSHProcessMessagesUntilEventsEx()機能であり、「多分待つ」を実装しますWinformsアプリケーションのディスパッチャループが再入力されます。 MouseUp条件を再度検出し、イベントハンドラを再度トリガします。

それはすぐに後のイベントがある実行されるように)あなたがOSを修正することはできませんが、回避策はリエントラントの問題を引き起こすイベントハンドラの普遍的な一つであり、あなたがきれい(BeginInvokeを持つトリッキーなコードを遅らせることができます処理された。このように:

private void listView1_MouseUp(object sender, MouseEventArgs e) { 
    this.BeginInvoke(new Action(() => { 
     Process.Start(@"C:\"); 
    })); 
} 
+0

偉大な深い説明と作業のソリューションに感謝します!コードは意図したとおりに動作していて、私は何かを学んだ;-) – MatzeBrei

関連する問題