2012-01-12 136 views
4

我正在使用C#中的一個小應用程序來刷新網頁,直到滿足一些條件。我有一個「火」=開始刷新按鈕和一個「停止!」應該停止操作的按鈕。我的問題是,它需要2次嘗試點擊停止按鈕,而不是1,下面是我的代碼:我的按鈕需要兩次點擊而不是一次

更新代碼計時器。不過我認爲可以更好地使用計時器,我認爲在第一次2-3次刷新之後它不會每秒更新一次,或者根本不刷新。我的代碼中是否存在任何我無法檢測到的缺陷?

private void FireButtonClick(object sender, EventArgs e) 
{ 

    try 
    { 
     if (webBrowser1.Url.ToString().StartsWith("some url")) 
     { 
      _stopped = false; 
      _timer.Tick += new EventHandler(RefreshBrowser); 
      _timer.Interval = (1000) * (1); 
      _timer.Enabled = true; 
      _timer.Start(); 
     } 
     else 
     { 
      MessageBox.Show("You must logon first."); 
      return; 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

private void RefreshBrowser(object sender, EventArgs e) 
{ 
    string content = "disabled"; 
    string baseUrl = @"http://some url"; 
    string newUrl = string.Empty; 
    string buttonXpath = @"/html/body/div/div[6]/table/tr/td[2]/table/tr/td/table/tr/td/table/tr[3]/td[2]/div[4]/a"; 
    webBrowser1.Refresh(); 
    _proceed = false; 
    if (!content.ToLower().Equals("disabled") && !_stopped) 
    { 

     if (!_stopped) 
     { 
      HtmlAgilityPack.HtmlDocument htmlDocument = new HtmlAgilityPack.HtmlDocument(); 
      htmlDocument.LoadHtml(webBrowser1.DocumentText); 
      HtmlNode node = htmlDocument.DocumentNode.SelectSingleNode(buttonXpath); 
      content = node.GetAttributeValue("disabled", string.Empty); 
      newUrl = node.GetAttributeValue("href", string.Empty); 
     } 
    } 
    else 
    { 

     webBrowser1.Navigate(baseUrl + newUrl); 
    } 


} 

private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e) 
{ 
    _proceed = true; 
    urlTextBox.Text = webBrowser1.Url.ToString(); 
} 

private void MainPageButtonClick(object sender, EventArgs e) 
{ 
    try 
    { 
     webBrowser1.Navigate(_mainPage); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

private void GoButtonClick(object sender, EventArgs e) 
{ 
    try 
    { 
     webBrowser1.Navigate(urlTextBox.Text); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 

} 

private void StopButtonClick(object sender, EventArgs e) 
{ 
    _timer.Stop(); 
    _proceed = true; 
    _stopped = true; 
} 

}

回答

3

你真的應該修改代碼以使用定時器。當您誤用GUI線程並定期致電Application.DoEvents();時,點擊只能在該位置處理,這意味着您必須進入循環才能處理事件。

這是絕對沒有去GUI編程。請改用計時器。

Here是定時器可如何被用來週期性地調用的方法的示例。在你的情況下,執行頁面的刷新。

+0

我用一些'Timer'編輯了我的問題。 – iCantSeeSharp 2012-01-12 13:24:56

+0

我不是100%確定的,但我認爲有時會在頁面加載前刷新頁面。 – iCantSeeSharp 2012-01-12 13:32:50

+0

是的你是對的,將調用移動到RefreshBrowser方法的底部。它應該被稱爲'導航' – jdehaan 2012-01-12 14:20:46

0

我的猜測是,你是停留在for循環中,不能停止,直到這個循環結束。這就是爲什麼它似乎需要兩次點擊,事實上它只是在等待停止。

嘗試而不是使用執行網頁刷新的線程並調用thread.run()在你的運行按鈕點擊使用Thread.stop()在你停止按鈕點擊。由於網頁刷新將在單獨的線程中發生,因此永遠不會干擾您的UI交互。

2

在我看來,這是因爲你在同一個線程執行的一切,所以當你的代碼運行沒有用戶界面的交互是可能的(=第一次單擊),並且在頁面重新加載UI交互是可能的(=第二點擊)。如果這是問題,請在單獨的線程中執行您的刷新邏輯。

喜歡的東西:

private void FireButtonClick(object sender, EventArgs e) 
{ 
    Thread worker = new Thread(new ThreadStart(delegate() 
    { 
     //your code 
    }); 
    worker.IsBackground = true; //so it does not block the app from being closed 
    worker.Start(); 
} 

如果在線程訪問UI的元素,你還需要使用Invoke

+3

這在我看來對於初學者來說太麻煩了,Timer更適合,因爲它允許直接調用GUI元素(它在GUI上調用)+需要睡眠和循環來執行重複任務。基本上你需要重新編碼一個計時器:-) – jdehaan 2012-01-12 12:46:05

+0

@jdehaan:我同意你是否只想每隔x秒執行一次refrehs,但我讀了這個問題和例子來連續地完成它。但是,無論如何,它會更好地使用計時器,因爲它不會使用那麼多的資源,並且用戶expirience應該大致相同。 – ChrFin 2012-01-12 12:51:02