1

我想制作一个控制台程序来监控网页的 htmlsourcecode,因为某些页面内容是由一些 javescript 创建的,所以我必须使用 webbrowser 控件。like :在 C# 中查看生成的源代码(在 AJAX/JavaScript 之后)

我的代码如下:

public class WebProcessor
{
    public string GeneratedSource;
    public string URL ;

    public DateTime beginTime;
    public DateTime endTime;

    public object GetGeneratedHTML(object url)
    {
        URL = url.ToString();
        try 
        {
            Thread[] t = new Thread[10];

            for (int i = 0; i < 10; i++) 
            {
                t[i] = new Thread(new ThreadStart(WebBrowserThread));
                t[i].SetApartmentState(ApartmentState.STA);
                t[i].Name = "Thread" + i.ToString();
                t[i].Start();
                //t[i].Join();          
            }

        } 
        catch (Exception ex) 
        {
            Console.WriteLine(ex.ToString());
        }

        return GeneratedSource;
    }

    private void WebBrowserThread()
    {
        WebBrowser wb = new WebBrowser();
        wb.ScriptErrorsSuppressed = true;

        wb.DocumentCompleted += 
            new WebBrowserDocumentCompletedEventHandler(
                wb_DocumentCompleted);

        while(true )
        {
            beginTime = DateTime.Now;

            wb.Navigate(URL);

            while (wb.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            Thread.Sleep(new Random().Next(10,100));
            }
        }               

        //wb.Dispose();                 
    }

    private void wb_DocumentCompleted(object sender, 
        WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser wb = (WebBrowser)sender;
        if (wb.ReadyState == WebBrowserReadyState.Complete)
        {
            GeneratedSource= wb.Document.Body.InnerHtml;

            endTime = DateTime.Now;
            Console.WriteLine("WebBrowser " + (endTime-beginTime).Milliseconds + Thread.CurrentThread.Name + wb.Document.Title);            
        }
    } 
}

当它运行时,经过一段时间(20-50次),它会抛出这样的异常

----------------------------------------------------------------------------
EXCEPTION code=ACCESS_VIOLATION
(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(nul
l)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(n
ull)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)
(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(null)(nul
l)(null)BACKTRACE: 33 stack frames:
 #0 0x083dba8db0 at MatchExactGetIDsOfNames in mshtml.dll
 #1 0x0879f9b837 at StrongNameErrorInfo in mscorwks.dll
 #2 0x0879f9b8e3 at StrongNameErrorInfo in mscorwks.dll
 #3 0x0879f9b93a at StrongNameErrorInfo in mscorwks.dll
 #4 0x0879f9b9e0 at StrongNameErrorInfo in mscorwks.dll
 #5 0x0879f9b677 at StrongNameErrorInfo in mscorwks.dll
 #6 0x0879f9b785 at StrongNameErrorInfo in mscorwks.dll
 #7 0x0879f192a8 at InstallCustomModule in mscorwks.dll
 #8 0x0879f19444 at InstallCustomModule in mscorwks.dll
 #9 0x0879f194ab at InstallCustomModule in mscorwks.dll
 #10 0x0879fa6491 at StrongNameErrorInfo in mscorwks.dll
 #11 0x0879f44bcf at DllGetClassObjectInternal in mscorwks.dll
 #12 0x089bbafa at  in
 #13 0x087b18cc10 at  in System.Windows.Forms.ni.dll
 #14 0x087b91f4c1 at  in System.Windows.Forms.ni.dll
 #15 0x08d00669 at  in
 #16 0x08792d6e46 at  in mscorlib.ni.dll
 #17 0x08792e02cf at  in mscorlib.ni.dll
 #18 0x08792d6dc4 at  in mscorlib.ni.dll
 #19 0x0879e71b4c at  in mscorwks.dll
 #20 0x0879e896ce at  in mscorwks.dll
 #21 0x0879e96ea9 at CoUninitializeEE in mscorwks.dll
 #22 0x0879e96edc at CoUninitializeEE in mscorwks.dll
 #23 0x0879e96efa at CoUninitializeEE in mscorwks.dll
 #24 0x0879f88357 at GetPrivateContextsPerfCounters in mscorwks.dll
 #25 0x0879e9cc8f at CoUninitializeEE in mscorwks.dll
 #26 0x0879e9cc2b at CoUninitializeEE in mscorwks.dll
 #27 0x0879e9cb51 at CoUninitializeEE in mscorwks.dll
 #28 0x0879e9ccdd at CoUninitializeEE in mscorwks.dll
 #29 0x0879f88128 at GetPrivateContextsPerfCounters in mscorwks.dll
 #30 0x0879f88202 at GetPrivateContextsPerfCounters in mscorwks.dll
 #31 0x0879f0e255 at InstallCustomModule in mscorwks.dll
 #32 0x087c80b729 at GetModuleFileNameA in KERNEL32.dll
----------------------------------------------------------------------------

我尝试了很多方法来解决这个问题,最后,我发现如果我的线程睡眠多毫秒,它会运行更长的时间,但仍然抛出异常。

希望有人给我如何解决这个问题的答案......非常感谢!

4

1 回答 1

0

你从哪里得到异常(我的意思是行号)。我想它正在通话wb.ReadyState != WebBrowserReadyState.Complete中,因为您正在从与创建控件实例的线程不同的线程上的控件中检索一些数据。如果是这种情况,那么您必须从正确的线程调用该属性。

我会将您的 while 循环更改为:

System.Windows.Forms.WebBrowserReadyState state = GetState(Program.BrowsingSystem.BrowserLink);
        while (state != System.Windows.Forms.WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
            Thread.Sleep(new Random().Next(10, 100));
        }

将其与以下调用的方法相关联:

private System.Windows.Forms.WebBrowserReadyState GetState(System.Windows.Forms.WebBrowser instance)
    {
        if (instance.InvokeRequired)
        {
            var wbFunc = new Func<System.Windows.Forms.WebBrowser, System.Windows.Forms.WebBrowserReadyState>(RetrieveState);
            IAsyncResult FunFuncResult = wbFunc.BeginInvoke(instance, null, null);
            return wbFunc.EndInvoke(FunFuncResult);

        }
        else
        {
            return RetrieveState(instance);
        }
    }

    public System.Windows.Forms.WebBrowserReadyState RetrieveState(System.Windows.Forms.WebBrowser instance)
    {
        return instance.ReadyState;
    }

我无法测试它,因为我错过了应用程序的其余部分,但它应该接近最终解决方案。

于 2012-07-09T22:53:27.653 回答