2016-04-28 79 views
2

我有一個方法browseWebsite(),它使用瀏覽器控件瀏覽網站以自動更改該網站內的數據。 webbrowser控件在方法執行時被實例化。不幸的是,部分被打開的網站是通過ajax加載的,因此webbrowser控件無法檢測到網站加載完成的正確時間,這意味着我無法使用DocumentCompleted事件在頁面加載時進一步移動。爲了解決這個問題,我實例化一個System.Windows.Forms.Timer,等待10秒鐘,直到他讓瀏覽器在網站上繼續前進。 (線程睡眠不工作,因爲web瀏覽器與線程一起凍結和停止加載過程) 整個事情是這樣的:在新線程中的C#計時器

 private void Form1_Load(object sender, EventArgs e) 
     { 
      Thread thread = new Thread(() => browseWebsite()); 
      thread.SetApartmentState(ApartmentState.STA); 

      thread.Start(); 

     } 

     public void browseWebsite() 
     { 
      WebBrowser browser = new WebBrowser(); 

      browser.Navigate("somesite"); 
     Timer waitTimer = new Timer(); 
     waitTimer.Interval = 10000; 
     waitTimer.Tick += delegate (object sender, EventArgs e) { WaitTimer_Tick(sender, e, browser); }; 

     waitTimer.Start(); 
    } 

    private void WaitTimer_Tick(object sender, EventArgs e, WebBrowser browser) 
    { 
     browser.Navigate("somewhere else"); 
    } 

由於整個過程這種方法確實是相當漫長和複雜的,我不我不想搞亂我的主線程,其中有50個webrowsers在它內部單擊,我想在另一個線程中啓動該過程。不幸的是,線程在達到方法的最後一行時死亡,並且帶着web瀏覽器和計時器。有沒有辦法像這樣實例化一個程序?或保持線程活着?

+0

沒有線程!?使用另一個計時器:System.Timers.Timer或更好的System.Threading.Timer。 – JeffRSon

+0

我的不好,改變了Form1_Load事件。 – colosso

+0

線程不會「死」 - 它已完成。或者你有例外嗎?您需要在線程內等待 - 查看AutoResetEvent或ManualResetEvent。並使用另一個計時器。 – JeffRSon

回答

1

可以使用無參數Application.Run方法重載

開始運行當前線程上的標準應用程序消息循環,沒有一種形式。

public void browseWebsite() 
{ 
    // ... 
    waitTimer.Start(); 
    Application.Run(); 
} 

但請注意,在以後的某個點(在完成處理後),您將需要調用Application.ExitThread方法(確保你在同一個線程調用它)

退出消息在當前線程上循環並關閉線程上的所有窗口。

最後,沒有直接關係,但使用這樣的線程時,這是很好的設置Thread.IsBackgroundtrue爲了不阻止時,主線程(主應用程序線程)終止終止您的應用程序的過程。

+0

完美的作品!非常感謝你!並感謝您指出Thread.IsBackground。這在某些時候會成爲問題! – colosso

+0

雖然它的工作原理,我不認爲這是一個很好的解決方案。除了使用錯誤的定時器類以外,沒有其他消息循環的原因。如何從正確的線程調用Application.ExitThread並不太明顯。 – JeffRSon

+0

@JeffRSon它不是**另一個**消息循環。 OP創建一個新的STA線程,在其上分配UI組件('WebBrowser','Timer'),所以它確實需要一個消息循環。 **另一個**(嵌套)消息循環是當你調用'Application.DoEvents'時。 –