新线程中的C#计时器

时间:2016-04-28 07:54:37

标签: c# multithreading winforms

我有一个方法browseWebsite(),它使用webbrowser控件浏览网站,以自动更改该网站中的数据。当方法执行时,webbrowser控件将被实例化。遗憾的是,打开的网站部分是通过ajax加载的,因此webbrowser控件无法检测到加载网站完成的正确时间,这意味着我无法在加载页面时使用DocumentCompleted事件进一步移动。为了解决这个问题,我实例化System.Windows.Forms.Timer等待10秒,直到他让浏览器在网站上进一步移动。 (线程休眠不起作用,因为webbrowser与线程一起冻结并停止加载过程) 整件事看起来像这样:

        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个浏览器在其中点击,我想在内部启动该过程另一个线程。不幸的是,当到达方法的最后一行时线程就会死掉,并使用web浏览器和计时器。有没有办法实例化这样的程序?还是保持线程活着?

1 个答案:

答案 0 :(得分:1)

您可以使用无参数Application.Run方法重载

  

开始在当前线程上运行标准的应用程序消息循环,没有表单。

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

但请注意,稍后(完成处理时),您需要调用Application.ExitThread方法(确保从同一个线程调用它)

  

退出当前线程上的消息循环并关闭线程上的所有窗口。

最后,没有直接关联,但在使用此类线程时,将Thread.IsBackground设置为true以便在主线程(主要线程)时不会阻止您的应用进程终止应用程序线程)终止。