2013-05-13 3 views
2

다음과 같은 코드가 있습니다. 이것은 기본적으로 내가 다른 스레드에서 만든 웹 브라우저 컨트롤, "스레드 1"에 대한 몇 가지 방법을 호출하고 "스레드 2"다른 스레드에서 호출 된 대리자로부터 C# 예외 잡기

WebBrowser browser = this.webBrowser  
browser.Invoke(new MethodInvoker(delegate { browser.Document.GetElementById("somebutton").InvokeMember("click"); })); 
Thread.Sleep(500); 
browser.Invoke(new MethodInvoker(delegate { browser.Document.GetElementById("username").SetAttribute("value", username); })); 
//folowed by several more similar statments 

에서 실행되고 있습니다.

브라우저에로드 된 현재 페이지의 요소에 "somebtn"또는 "username"요소가 없으면 "스레드 1"에서 예외가 발생합니다.

"스레드 2"에서 해당 예외를 잡을 방법이 있습니까? 나는 델리게이트 내에서 캐치 시도를 사용할 수 있고 예외 (exception)와 같은 값을 리턴하는 특별한 델리게이트를 가질 수 있다는 것을 알고 있지만, 그 옵션 주위에는 어떤 방법이 있나?

참고 : * 특정 페이지가 특정 이벤트 사이에 약간의 지연이 필요하므로 Thread.Sleep이 필요합니다. 이러한 이벤트를 단일 대리자로 결합하는 방법이 있다면 (일부 형태의 비 차단 지연을 유지하면서) 작동 할 수 있다고 생각합니다. 모든 이벤트를 하나의 catch로 래핑하고 예외를 반환하는 대리자를 만듭니다. .

+0

나는'WebBrowser' 클래스에서 MSDN에서 살펴 경우 (http://msdn.microsoft.com/en-us/library/cc491073.aspx)는 내가 어떤'Invoke' 방법을 볼 수 없습니다. 어느 쪽을 사용하고 있습니까? –

+0

Invoke는 모든 UI 컨트롤의 한 메서드입니다. 다른 스레드와 같은 컨트롤을 업데이트 할 수 있습니다. – user871289

+0

가정이 사실이고 Control.Invoke를 호출하면 모든 대리자가 UI 스레드에서 호출됩니다. 그래서 ... 같은 실에서. 너가 원하는게 그거야? –

답변

2

는 UI 스레드를 통해 위임 실행 - 그것은 여전히 ​​동기 호출을. 대리자가 실행을 완료하거나 예외가 throw 될 때까지 동기 의미 Invoke이 반환되지 않습니다. 거기에 던져진 예외를 잡을 수 있습니다.

WebBrowser browser = this.webBrowser; 
try {  
    browser.Invoke(new MethodInvoker(delegate { browser.Document.GetElementById("somebutton").InvokeMember("click"); })); 
    Thread.Sleep(500); 
    browser.Invoke(new MethodInvoker(delegate { browser.Document.GetElementById("username").SetAttribute("value", username); })); 
} catch(Exception e) 
{ 
    //catch in Thread 2 
} 
1

WebBrowser.Invoke를 사용하는 경우 모든 대리자는 사용자 인터페이스의 스레드에서 실행됩니다. 그래서 모든 것이 하나의 스레드에서 실행됩니다. 그래서 질문에 UI 스레드가 자체 기다리고 싶어?

여러 옵션이 있습니다,하지만 난 한 가장 간단한 표시됩니다 :이 없습니다 당신이 원하는 무엇을 가정 할 때, 나는 내 대답에 약간의 "자유"를했다

  • 를 시작에게 모두 위임을 BeginInvoke와 함께.
  • thread1의 IAsyncResult을 로컬 변수에 저장하십시오.
  • Thread2가 작업을 수행합니다.
  • 스레드 2는 thread1의 EndInvoke을 수행합니다.

코드 : Control.Invoke() 비록

WebBrowser browser = this.webBrowser; 
MethodInvoker thread1 = delegate 
{ 
    browser.Document.GetElementById("somebutton").InvokeMember("click"); 
}; 
IAsyncResult result1 = thread1.BeginInvoke(null, null); 
Thread.Sleep(500); 
MethodInvoker thread2 = delegate 
{ 
    browser.Document.GetElementById("username").SetAttribute("value", username); 
    try 
    { 
     thread1.EndInvoke(result1); 
    } 
    catch (Exception ex) 
    { 
     // Exception of thread1. 
    } 
}; 
thread2.BeginInvoke(null, null);