簡體   English   中英

如何等待c#webbrowser在TPL中完成文檔加載

[英]how to wait c# webbrowser to complete document load in TPL

嗨,我有兩個代碼塊

當我在瀏覽器中導航到一個網址並嘗試等待它時,我認為這是一個僵局=)任何幫助建議都非常感謝!

我只是在這里添加更多文字,所以我可以發布問題:/抱歉

foreach (var davaType in davaTypes)
        {
            Parallel.ForEach(years, year =>
            {
                ts.Add(Task.Run(() =>
                {
                    var th = new Thread(async () =>
                    {
                        await doWorkAsync(year, davaType, tarafType);

                        Application.Run();

                    });
                    th.IsBackground = true;
                    th.SetApartmentState(ApartmentState.STA);
                    th.Start();
                }));

            });

        }

public static async Task doWorkAsync(int year, string davaType, string tarafType)
        {
            using (var browser = new MyBrowser())
            {
                Console.WriteLine("Im Created Here");
                 browser.Navigate("some url");

                while (!browser.MyLoaded)
                {
                    Console.WriteLine("waiting");
                    await Task.Delay(10);
                }

                Console.WriteLine("complete");
                browser.Document?.GetElementById("DropDownList1")?.SetAttribute("value", davaType);
                browser.Document.GetElementById("DropDownList3")?.SetAttribute("value", tarafType);
                browser.Document.GetElementById("DropDownList4")?.SetAttribute("value", year.ToString());
                browser.Document.GetElementById("Button1").MyClick();
                await browser.WaitPageLoad(10);
                Console.WriteLine("Im DoneHere");

            }


        }

您可以使用TaskCompletionSource創建任務,並在加載頁面后等待它。

請參閱: UWP WebView等待導航

您只需要為WinForms創建一個單獨的線程。 其他線程將由各個瀏覽器本身創建。 您需要的是處理他們的DocumentCompleted事件。 文檔第一次完成后,您輸入並提交數據,第二次完成后,您將獲得結果。 當所有瀏覽器都完成后,退出winforms線程就完成了。

注意:要從winforms線程啟動機器人,我使用了Idle事件處理程序,因為它是我想到的第一個解決方案。 你可能會找到更好的方法。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleBrowsers
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "https://your.url.com";
            string[] years = { "2001", "2002", "2003"};
            string[] davas = { "1", "2", "3" };
            string taraf = "1";

            int completed = 0, succeeded = 0;
            var bots = new List<Bot>();
            var started = false;

            var startBots = (EventHandler)delegate (object sender, EventArgs b)
            {
                if (started)
                    return;

                started = true;
                foreach (var dava in davas)
                    foreach (var year in years)
                        bots.Add(new Bot { Year = year, Dava = dava, Taraf = taraf, Url = url }.Run((bot, result) =>
                        {
                            Console.WriteLine($"{result}: {bot.Year}, {bot.Dava}");
                            succeeded += result ? 1 : 0;
                            if (++completed == years.Length * davas.Length)
                                Application.ExitThread();
                        }));
            };

            var forms = new Thread((ThreadStart) delegate {
                Application.EnableVisualStyles();
                Application.Idle += startBots;
                Application.Run();
            });

            forms.SetApartmentState(ApartmentState.STA);
            forms.Start();
            forms.Join();

            Console.WriteLine($"All bots finished, succeeded: {succeeded}, failed:{bots.Count - succeeded}.");
        }
    }

    class Bot
    {
        public string Url, Dava, Taraf, Year;
        public delegate void CompletionCallback(Bot sender, bool result);

        WebBrowser browser;
        CompletionCallback callback;
        bool submitted;

        public Bot Run(CompletionCallback callback)
        {
            this.callback = callback;

            browser = new WebBrowser();
            browser.ScriptErrorsSuppressed = true;
            browser.DocumentCompleted += Browser_DocumentCompleted;
            browser.Navigate(Url);
            return this;
        }

        void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (browser.ReadyState == WebBrowserReadyState.Complete)
            {
                if (submitted)
                {
                    callback(this, true);
                    return;
                }

                var ok = SetValue("DropDownList1", Dava);
                ok &= SetValue("DropDownList3", Taraf);
                ok &= SetValue("DropDownList4", Year);
                if (ok)
                    ok &= Click("Button1");

                if (!(submitted = ok))
                    callback(this, false);
            }
        }

        bool SetValue(string id, string value, string name = "value")
        {
            var e = browser?.Document?.GetElementById(id);
            e?.SetAttribute(name, value);
            return e != null;
        }

        bool Click(string id)
        {
            var element = browser?.Document?.GetElementById(id);
            element?.InvokeMember("click");
            return element != null;
        }
    }
}

我之前遇到過這個問題,我申請的解決方案如下;

 private void waitTillLoad()
    {
        WebBrowserReadyState loadStatus = default(WebBrowserReadyState);
        int waittime = 100000;
        int counter = 0;
        while (true)
        {
            loadStatus = webBrowser1.ReadyState;
            Application.DoEvents();

            if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
            {
                break; // TODO: might not be correct. Was : Exit While
            }
            counter += 1;
        }
        counter = 0;
        while (true)
        {
            loadStatus = webBrowser1.ReadyState;
            Application.DoEvents();

            if (loadStatus == WebBrowserReadyState.Complete)
            {
                break; // TODO: might not be correct. Was : Exit While
            }

            counter += 1;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM