我写了一个抓网站数据的Windows服务程序,当初用winform写的时候是没有错误的。但是改成服务就出现了问题,我不知道是不是多线程的问题。因为我用的webbrowser类来抓取网站的数据,因为webbrowser本身就带有一个线程,我又用到了timer控件来确定10秒重新获取一下网站的数据。而我要写的是单线程,所以这里就有2个线程了,但是我在mian()这添加了[STAThread],把webbrowser放在主线程这里。然后调试的时候出现了错误。
if (web1.Document.Body != null)
{
                    IHTMLDocument2 doc = web1.Document.DomDocument as IHTMLDocument2;
                    string innerhtml = doc.body.innerHTML;                          //获取html源码
                    string innertext = doc.body.innerText; 
}
错误出现在 web1.Document.Body != null  
错误:“由于以前的函数求值超时,函数求值被禁用。必须继续执行才能重新启用函数求值。”1.我抓取的这个网站必须要用webbrowser才能获取源码,其他的httpwebquest、WebClient等是获取不到的。至少我用它们的时候没获取到。2.我用winform写的时候是正确的,没有任何错误。3.Windows服务现在我也可以调试,错误就是这样找出来的。希望各位大大帮忙,给小弟点思路这是什么情况。
谢谢各位。

解决方案 »

  1.   

    http://topic.csdn.net/t/20020705/10/851752.html
      

  2.   

    抓网站数据,可以不用webBrowser。
    建议你再把你的timer去掉,再看看。
      

  3.   


    去掉timer?那怎么10秒刷新一次数据?
      

  4.   


    你不但不该谢,反倒应该骂,如果你用GooGle搜索"web1.Document.Body != null",下面会有更多提示关键字"document.body null",然后点击那个链接搜索"document.body null",第一个查找结果就是http://topic.csdn.net/t/20020705/10/851752.html的链接,这是极度不负责任的做法,如果可以这么做,楼主你也没必要在这里提问了.
      

  5.   


    唉,惭愧,惭愧,确实是第一个就是http://topic.csdn.net/t/20020705/10/851752.html,当初我搜索"web1.Document.Body != null"的时候发现就只有2个,没有想到下面的提示关键字了,因为要的很急,而一直都解决不了,希望大大谅解。毕竟不管谁怎么回帖,都应该感谢。同时非常感谢“青龙白虎”大大。
      

  6.   

    Windows服务调用窗体控件要注意
      

  7.   

    http://gbigone.blog.163.com/blog/static/35001529200961593948678/
    web1 :是什么控件名,问题估计就是这个,转成服务以后可能有些调用不到
      

  8.   

    可以参考一下:http://www.csccd.net/news/20090119162724482.html
      

  9.   


    web1 是webbrowser的对象名:
      

  10.   

    HtmlDocument htmlDoc = webBrowser.Document;
    HtmlElement btnElement = htmlDoc.All["btnClose"];
    if (btnElement != null)
    {}
    改为判断btnElement 内容可以不
      

  11.   

    应该是这样,你的服务里有webbrowser的控件,还是动态申明的,
    窗体程序有webbrowser的控件,服务里webbrowser要动态申明一个
      

  12.   

    你web1的申明程序请显示一下,我帮你看看有没有问题
      

  13.   

    你web1的申明程序请显示一下,看一下在服务中能否被找到web1
      

  14.   

    webbrowser web1 = new webbrowser();.......
    if(web1.document.body!=null)          //这里本来一般情况它是可以得到的。但是我抓取的网站是需要加载的,这样的话,我们不能规定延迟几秒钟,同时,我还必须是每10秒钟又要重新获取数据,因为我抓的数据是时时刻刻在变动的。      并且我认为这应该是多线程的问题,但是在网上一直没看到类似的例子。
    {
      ....
    }
      

  15.   

    我继续查,先参考这个
    http://topic.csdn.net/u/20080628/13/bba4b615-5636-46f9-a1df-063cf9960a2e.html
    估计是超时了
      

  16.   

    windows服务 不能使用windows.form.timer控件,而是使用System.Timers.Timer控件
      

  17.   

    用Webbrowser控件加载网页时,通常会用DocumentCompleted事件来指示网页加载完毕。但当加载的网页包含frame时,可能会多次触发该事件,所以不能简单地通过它来判断网页加载完毕。要通过WebBrowserNavigatedEventArgs来判断。private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (e.Url != webBrowser1.Document.Url) return;
     
        // 当 e.Url == webBrowser1.Document.Url 我们要的网页加载完毕
        // 加载完毕
        // ...
    }
      

  18.   


    恩,我用的是timer.timer控件,就因为这样才导致线程的问题,因为timer.timer就是个线程。
      

  19.   


    private void web1_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
            {        }
            [STAThread]
            private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                System.Threading.Thread.Sleep(1000);
                web1.Navigate(url);            web1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(web1_DocumentCompleted);
                //tt2.Stop();
                timer1.Interval = 10000;
                btnStart();
            }
    这是我写的判断。
      

  20.   

    多线程参考这个:http://www.i-ok.net/csharp/articles/glxn3dok.htm
      

  21.   

     C# WebBrowser 当前线程不在单线程单元中,因此无法实例化的错误
    参考这个:
    http://zhidao.baidu.com/question/62226910.html
      

  22.   

    是的。这个程序我用winform窗体已经是写过一次的。它是没有任何问题的,只是现在改成服务,出现了这种情况,不知道怎么解决。虽然还是没到点,但是还是十分感谢。费心了。
      

  23.   

    能否设置超时,我以前写过DELPHI服务抓天气预报
    http://topic.csdn.net/u/20080610/17/ca604952-d5a6-47ab-a981-5c6ee8a5e6fd.html
      

  24.   


            delegate void DoThingCallBack();
            private void button1_Click(object sender, EventArgs e)
            {
                  t1 = new Thread(new ThreadStart(caozuo1));
                  t1.Start();
            }
            private void caozuo1()
            {
                if (webBrowser1.InvokeRequired)
                {
                    DoThingCallBack cb = new DoThingCallBack(caozuo1);
                    this.Invoke(cb);
                }
                else
                {
                    HtmlElement guanli = webBrowser1.Document.All["Login"];
                }
            }代碼有判斷webBrowser1.InvokeRequired,也就是當需要的時候才使用委托,而不是任何時候都使用。 
      

  25.   

    应该是多线程问题,你在Timer 的timer1_Elapsed时间里边刚开始就把timer禁用掉然后在执行,执行完后再启用timer,否则多线程并发容易死锁
      

  26.   

    怎么可能?那弄个静态BOOL把执行的那段代码锁掉。只执行一次,看看还有错吗?
      

  27.   


    如果这样的话,Windows服务它就运行不了了,它会出现:服务启动,但是似乎没有什么可执行的,又关闭了。
      

  28.   

     [STAThread] 
            private HtmlElementCollection HtmlTR_Content(string strWeb, string tj)
            {
                try
                {                //生成HtmlDocument
                    WebBrowser webb = new WebBrowser();我也遇到跟你差不多的问题,我的也是抓取数据,但是在网也上他就报   这个错误

    当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d 

    顶到 沙发上
      

  29.   

    [STAThread] 
            private HtmlElementCollection HtmlTR_Content(string strWeb, string tj) 
            { 
                try 
                {                 //生成HtmlDocument 
                    WebBrowser webb = new WebBrowser(); 我也遇到跟你差不多的问题,我的也是抓取数据,但是在网也上他就报  这个错误 当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d 
    一模一样的错无   顶 到楼主上