c#WebBrowser DocumentText工作一次但不在循环中?

时间:2013-08-22 20:21:11

标签: c# loops while-loop webbrowser-control

我有兴趣检查网站的内容,内容经常更改,当我在任何浏览器上查看网站时,它每30秒刷新一次。我想知道内容何时发生变化。

我正在使用winforms,我只想点击一个按钮开始循环,每30秒一次。我不想太频繁地访问网站,事实上网页自己的刷新对我的需求来说已经足够了。

当我点击按钮(btnCheckWebsite)时,我的代码有效,如果我等一下再点击btnCheckWebsite,我的消息框会弹出,因为网页已经更改。这很好但是我想在while循环中执行此操作。当我取消注释我的while循环时,DocumentText永远不会改变。我已经调试了它,并且由于某种原因它每次都是相同的文本,即使在现实世界中网页发生了变化,它在我的代码中保持不变。

所以我的问题是为什么我不能使用循环,而我可以做什么而不是在没有任何输入的情况下重复运行?

作为奖励,我想删除.Refresh()我添加了这个,因为没有它就无法工作但是据我所知,这会刷新整个页面。当我使用浏览器时,即使我不刷新整个页面,我也会看到页面更新。

仅仅为了获取背景信息,我确实从表单上创建了一个WebBrowser控件,页面自动刷新。我使用相同的代码,并有相同的问题,有趣的是,我的Windows窗体上的WebBrowser控件本身刷新没问题,直到我点击btnCheckWebsite然后它停止刷新!我也知道webrequest,但我不知道如何将它用于我的目的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Check_Website
{
    public partial class Form1 : Form
    {
        public WebBrowser _memoryWebBrowser = new WebBrowser();
        String _previousSource = "emptySource";

        public Form1()
        {
            InitializeComponent();

           _memoryWebBrowser.Navigate(new Uri("http://www.randomurl.com/"));

        }

        private void btnCheckWebsite_Click(object sender, EventArgs e)
        {
            //I want to un-comment this while loop and let my code run itself but it stops working
            //when I introduce my while loop.

            //while (1 < 2 )
            //{
                //Thread.Sleep(30000);

                checkWebsite();

            //}
        }

        private void checkWebsite()
        {
            //Why do I need this refresh? I would rather not have to hit the web page with a refresh.
            //When I view the webpage it refreshed with new data however when I use a WebBrowser
            //the refresh just doesn't happen unless I call Refresh.
            _memoryWebBrowser.Refresh();

            Thread.Sleep(500);

            while (((_memoryWebBrowser.ReadyState != WebBrowserReadyState.Complete) || (_memoryWebBrowser.DocumentText.Length < 3000)))
            {
                Thread.Sleep(1000);
            }


            String source = _memoryWebBrowser.DocumentText;

            if ((source != _previousSource) && (_previousSource != "emptySource"))
            {
                //Hey take a look at the interesting new stuff on this web page!!
                MessageBox.Show("Great news, there's new stuff on this web page www.randomurl.co.uk!!" );
            }

            _previousSource = source;

        }
    }
}

4 个答案:

答案 0 :(得分:1)

您需要在DocumentCompleted事件后进行处理。此事件是异步的,因此如果要在循环中执行此操作,则执行线程必须为此事件引发消息。在WinFroms应用程序中,您的UI线程已经在Applicaiton.Run中传送消息,并且在同一线程上输入嵌套消息循环的唯一其他支持方式是通过模式形式(这里是it can be done的方式,请参阅评论)。 在没有嵌套消息循环的情况下执行此类Navigate / DocumentCompleted逻辑的另一种(IMO,更好)方法是使用async/await here's how 。在经典意义上,这不完全是一个循环,但从概念上和语法上来说,它可能正是你所寻找的。

答案 1 :(得分:0)

您可以捕获WebBrowser.Navigated事件以在重新加载页面时收到通知。所以你不需要循环。 (我的意思是准备好的循环)

只需每30秒浏览一次循环中的页面,在导航事件中,您可以检查网站是否已更改。

答案 2 :(得分:0)

你最好挂钩DocumentCompleted事件来检查它的DocumentText属性!

答案 3 :(得分:0)

WebBrowser元素非常多,并且需要很多开销。而不是你应该使用WebRequest。因为你说你不知道如何使用,这里有一个(工作)的例子。

using System;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace Check_Website
{
    public partial class Form1 : Form
    {
        String _previousSource = string.Empty;
        System.Windows.Forms.Timer timer;

        private System.Windows.Forms.CheckBox cbCheckWebsite;
        private System.Windows.Forms.TextBox tbOutput;

        public Form1()
        {
            InitializeComponent();

            this.cbCheckWebsite = new System.Windows.Forms.CheckBox();
            this.tbOutput = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // cbCheckWebsite
            // 
            this.cbCheckWebsite.AutoSize = true;
            this.cbCheckWebsite.Location = new System.Drawing.Point(12, 12);
            this.cbCheckWebsite.Name = "cbCheckWebsite";
            this.cbCheckWebsite.Size = new System.Drawing.Size(80, 17);
            this.cbCheckWebsite.TabIndex = 0;
            this.cbCheckWebsite.Text = "checkBox1";
            this.cbCheckWebsite.UseVisualStyleBackColor = true;
            // 
            // tbOutput
            // 
            this.tbOutput.Location = new System.Drawing.Point(12, 35);
            this.tbOutput.Multiline = true;
            this.tbOutput.Name = "tbOutput";
            this.tbOutput.Size = new System.Drawing.Size(260, 215);
            this.tbOutput.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.tbOutput);
            this.Controls.Add(this.cbCheckWebsite);
            this.Name = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

            timer = new System.Windows.Forms.Timer();
            timer.Interval = 30000;
            timer.Tick += timer_Tick;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (!cbCheckWebsite.Checked) return;

            WebRequest request = WebRequest.Create("http://localhost/check_website.html");
            request.Method = "GET";

            WebResponse response = request.GetResponse();

            string newContent;
            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                newContent = sr.ReadToEnd();
            }

            tbOutput.Text += newContent + "\r\n";

            if (_previousSource == string.Empty)
            {
                tbOutput.Text += "Nah. It's empty";
            }
            else if (_previousSource == newContent)
            {
                tbOutput.Text += "Nah. Equals the old content";
            }
            else
            {
                tbOutput.Text += "Oh great. Something happened";
            }

            _previousSource = newContent;
        }
    }
}