2017-04-04 5 views
2

내 Windows Forms 응용 프로그램에서 항목 중 하나가 클릭되면 특정 폴더가있는 새 탐색기 창을 열어야합니다. 내가Process.Start()를 사용할 때 WindowsForm MouseUp이 두 번 발생 함

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

는 탐색기 창을 두 번 열립니다하여 새 탐색기 창을 열면 지금 (내가 이미 내가 클릭 좌표를 필요로하는 일부 히트 감지를 가지고 있기 때문에) 내가 MouseUp 이벤트 청취하고있다. Process.Start(@"C:\");과 확실히 관련이 있습니다. 왜냐하면 정상적인 콘솔 출력으로 회선을 전환하면 방금 한 번 실행되기 때문입니다.

이미 처리 된 이벤트를 표시하거나 두 번째 실행을 무시하는 방법이 있습니까?

+0

코드를 단계별로 실행하여 코드가 두 번 실행되는지 확인합니다. –

+0

안녕하세요 발리 C, 방금 해봤습니다. 난 그냥 Console.WriteLine (e.Button); 나는 출력을 두 번 얻는다. 메서드 내에서 중단 점을 설정하는 것보다 한 번만 실행됩니다. 아마 새롭게 열린 탐색 창으로 초점이 바뀌었고 정말 빨리 돌아 왔을 까? 그러나 그것은 단지 추측 일뿐입니다. – MatzeBrei

+0

흠, 이상합니다. MouseUp이 아니라 MouseClick 이벤트를 사용해 보셨습니까? –

답변

5

이것은 재진입 버그으로 코드에서 DoEvents()를 사용할 때 발생하는 버그와 매우 유사합니다. 하지만이 경우 버그가 OS에 내장되어 있습니다. 이 문제의 도구는 Explorer입니다.이 코드에는 매우 특별한 활성화 모드가 있습니다. Process.Start()의 반환 값을 볼 때 볼 수있는 것은 null입니다. Process.Start()가 실제로 프로세스를 시작하지 않을 때 발생합니다.

두 번째에만 적용되는 조건부 중단 점을 사용하면 작동중인 버그를 볼 수 있습니다. 관리되지 않는 디버깅 및 기호 서버가 활성화 된 호출 스택은 다음과 같습니다

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

관련 문제