用于填写表单的异步webBrowser

时间:2015-06-04 14:14:28

标签: c# winforms asynchronous webbrowser-control

我需要让webBrowser导航到一个网站的几个不同但类似的URL,填写表格,点击发送按钮,然后阅读下一个网站以查明上一步是否成功。成功后,循环必须停止。

我坚持让webBrowser.Navigate("url");在循环中工作。 由于页面需要一些时间来加载它必须是异步的。

我对整个异步的东西都很陌生,所以我需要帮助。

  

我在https://stackoverflow.com/a/15936400/4972402上找到了这个解决方案,所以我把它拿来并把我的代码放进去填写表格并点击提交按钮。

public partial class Form1 : Form
{
    public struct WebBrowserAwaiter
    {
        private readonly WebBrowser _webBrowser;
        private readonly string _url;

        private readonly TaskAwaiter<string> _innerAwaiter;

        public bool IsCompleted
        {
            get
            {
                return _innerAwaiter.IsCompleted;
            }
        }

        public WebBrowserAwaiter(WebBrowser webBrowser, string url)
        {
            _url = url;
            _webBrowser = webBrowser;
            _innerAwaiter = ProcessUrlAwaitable(_webBrowser, url);
        }

        public string GetResult()
        {
            return _innerAwaiter.GetResult();

        }

        public void OnCompleted(Action continuation)
        {
            _innerAwaiter.OnCompleted(continuation);
        }

        private TaskAwaiter<string> ProcessUrlAwaitable(WebBrowser webBrowser, string url)
        {
            TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
            var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
            {
                // TODO: put custom processing of document here
                taskCompletionSource.SetResult(e.Url + ": " + webBrowser.Document.Title);
            });
            webBrowser.DocumentCompleted += handler;
            taskCompletionSource.Task.ContinueWith(s => { webBrowser.DocumentCompleted -= handler; });

            webBrowser.Navigate(url);
            return taskCompletionSource.Task.GetAwaiter();
        }
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ProcessUrlsAsync(new[] { "http://google.com", "http://microsoft.com", "http://yahoo.com" })
            .Start();
    }

    private Task ProcessUrlsAsync(string[] urls)
    {
        return new Task(() =>
        {
            foreach (string url in urls)
            {
                var awaiter = new WebBrowserAwaiter(webBrowser1, url);
                string result = awaiter.GetResult();

                MessageBox.Show(result);
            }
        });
    }
}   
    }
  

现在的问题是当我这样做时:

        private Task ProcessUrlsAsync(string[] urls)
    {
        return new Task(() =>
        {
            foreach (string url in urls)
            {
                var awaiter = new WebBrowserAwaiter(webBrowser1, url, this.currentKunde);
                string result = awaiter.GetResult();
                if (result != "failed")
                { break; }
                else
                {
                    MessageBox.Show(result);
                }
            }
        });
    }

private TaskAwaiter<string> ProcessUrlAwaitable(WebBrowser webBrowser, string url)
    {
        TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
        var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
        {
            // TODO: put custom processing of document here
            if (webBrowser.Document.Title == "Title")
            {
                        webBrowser.ScriptErrorsSuppressed = false;
                        webBrowser.Document.GetElementById("Name").SetAttribute("Value", this._currentCustomer.Displayedname);
                        webBrowser.Document.GetElementById("EMail").SetAttribute("Value", this._currentCustomer.Email);

                        //Turns off CheckInput()
                        webBrowser.Document.GetElementsByTagName("form")[2].SetAttribute("onsubmit", "");

                        //Clicks on the submit button
                        webBrowser.Document.GetElementById("sendbutton").InvokeMember("click");
            }
            else
            {
                //Do other stuff and return "success"

            }
            taskCompletionSource.SetResult("failed");
        });

如何在ckick之后再次触发处理程序,这样它会返回“成功”并停止循环?

0 个答案:

没有答案