2010-01-13 2 views
2

안녕하세요 저는 폼의 나머지 부분에서 올바른 스레드에 두 개의 웹 브라우저를 만들려고합니다. 하나는 tabpage1로 이동하고 다른 하나는 tabpage2에 추가됩니다. 첫 번째 브라우저는 page1을 잘 생성하지만 두 번째 브라우저는 추가되지 않고 "WebBrowser 컨트롤에 대한 창 핸들을 가져올 수 없습니다. 창없는 ActiveX 컨트롤은 지원되지 않습니다." 일어난다. 를 heres 내 코드 :두 번째 탭 페이지에 웹 브라우저 호출하기 Visual C#

private Thread t; 
WebBrowser webBrowser1, webBrowser2; 
public delegate void Addc1(Control o); 
public delegate void Addc2(Control o); 
public Addc1 AddControl1; 
public Addc2 AddControl2; 
public Form1() 
{ 
     InitializeComponent(); 
     AddControl1 = new Addc1(AddTabControl1); 
     AddControl2 = new Addc2(AddTabControl2);   
}   
private void button2_Click(object sender, EventArgs e) 
{ 
     t = new Thread(new ThreadStart(this.UIStart)); 
     t.SetApartmentState(ApartmentState.STA); 
     t.Start(); 
} 
public void UIStart() 
{ 
      WebBrowser webBrowser1 = new WebBrowser(); 
      webBrowser1.Location = new System.Drawing.Point(1,1); 
      webBrowser1.Size = new System.Drawing.Size(936, 35); 
      webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser2_DocumentCompleted); 
      tabPage1.Invoke(AddControl1, new Object[] { webBrowser1 }); 

      WebBrowser webBrowser2 = new WebBrowser(); 
      webBrowser2.Location = new System.Drawing.Point(1,1); 
      webBrowser2.Size = new System.Drawing.Size(936, 935); 
      webBrowser2.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.webBrowser2_DocumentCompleted);  
      tabPage2.Invoke(AddControl2, new Object[] { wedBrowser2 }); 


      webBrowser1.Navigate("www.ask.com"); 
      webBrowser2.Navigate("www.google.com"); 
     } 
     public void AddTabControl1(Control o) 
     { 
      tabPage1.Controls.Add(o); 
     } 
     public void AddTabControl2(Control o) 
     { 
      tabPage2.Controls.Add(o); 
     } 
} 

내가 webbrowser1 만들고 이동하지만, 다른 하나는 페이지 2의 컨트롤에 추가하지만 만들어지지 않습니다 것이라고 말했다있다. 어떤 아이디어? 덕분에 당신은 여러 스레딩 규칙을 위반하고

답변

5

을 추가

  • 웹 브라우저가 단일 스레드 아파트의 요구 사항을 ActiveX 컨트롤입니다. 스레드를 STA로 올바르게 설정하고 있지만 두 번째 요구 사항을 위반하고 있습니다. STA 스레드는 메시지 루프를 펌프해야합니다. 아직까지는 얻지 못했지만 DocumentCompleted 이벤트는 절대 실행되지 않습니다.
  • Windows는 하위 컨트롤이 부모와 동일한 스레드에 속해야합니다. 귀하의 경우, 불쾌한 불일치가 있습니다. AxHost 래퍼는 Controls.Add() 호출로 인해 UI 스레드에서 만들어 지지만 WebBrowser가 사용하는 기본 창 핸들은 그렇지 않을 수 있습니다. 나는 이것이 여러분이 얻는 예외의 근원이라고 생각합니다.

웹 브라우저는 의도 한대로 작동하지 않을 수 있습니다. 웹 브라우저는 단순히 여러 스레드를 처리 할 수있는 코드가 아닙니다. 올바른 스레드에서 생성하더라도 백그라운드 스레드에서 작성된 호출은 COM에 의해 STA 계약을 구현하기 위해 마샬링되며 동시성은 없습니다.

메시지 루프 (Application.Run)를 펌프하는 별도의 STA 스레드에서이 메서드를 사용하면 폼과 컨트롤을 동일한 스레드에서 만들어야합니다.

관련 문제