我的按钮需要两次点击而不是一次

问题描述:

我正在使用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; 
} 

}

你真的应该修改代码以使用定时器。当您误用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

我的猜测是,你是停留在for循环中,不能停止,直到这个循环结束。这就是为什么它似乎需要两次点击,事实上它只是在等待停止。

尝试而不是使用执行网页刷新的线程并调用thread.run()在你的运行按钮点击使用Thread.stop()在你停止按钮点击。由于网页刷新将在单独的线程中发生,因此永远不会干扰您的UI交互。

在我看来,这是因为你在同一个线程执行的一切,所以当你的代码运行没有用户界面的交互是可能的(=第一次单击),并且在页面重新加载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