异步/等待实现web浏览器类的.NET [英] Async/Await implementation of WebBrowser class for .NET

查看:242
本文介绍了异步/等待实现web浏览器类的.NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

隆泰读者,首次海报这里。

Longtime reader, first-time poster here.

我的目标:在使用web浏览器类要能够利用异步优势/等待。由于WebBrowser.Navigate(字符串URL)是一个异步方法,你不能检查HTML文档,直到LoadComplete事件。

My goal: To be able to take advantage of async/await while using the WebBrowser class. As the WebBrowser.Navigate(string url) is an asynchronous method, and you can't examine the html document until the LoadComplete event is fired.

下面是我的(工作)code到目前为止:

Here is my (working) code so far:

public class AsyncWebBrowser
{
    protected WebBrowser m_WebBrowser;

    private ManualResetEvent m_MRE = new ManualResetEvent(false);

    public void SetBrowser(WebBrowser browser) {
        this.m_WebBrowser = browser;
        browser.LoadCompleted += new LoadCompletedEventHandler(WebBrowser_LoadCompleted);
    }

    public Task NavigateAsync(string url) {
        Navigate(url);

        return Task.Factory.StartNew((Action)(() => {
            m_MRE.WaitOne();
            m_MRE.Reset();
        }));
    }

    public void Navigate(string url) {
        m_WebBrowser.Navigate(new Uri(url));
    }

    void WebBrowser_LoadCompleted(object sender, NavigationEventArgs e) {
        m_MRE.Set();
    }
}

这previous类现在允许我使用下列内容:

And this previous class now allows me to use the following:

public async void NavigateToGoogle() {
    await browser.NavigateAsync("www.google.com");
    //Do any necessary actions on google.com
}

不过,我想知道是否有处理这种更高效/有道。具体而言,Task.Factory.CreateNew与阻断ManualResetEvent的。感谢您的输入!

However, I am wondering if there is a more efficient/proper way of handling this. Specifically, the Task.Factory.CreateNew with the blocking ManualResetEvent. Thanks for your input!

推荐答案

首先,我认为这是一个很好的锻炼学习如何异步/等待工作。

First off, I think this is a great exercise for learning how async/await works.

您似乎火圈,以使NavigateAsync返回任务跳跃。但它没有返回一个任务,以便awaitable!是的的方法包含一个计谋的必须返回任务,而是一种方法,它的是awaitable 的需要无法返回任务;所有它做的是回到某种类型的,你可以调用GetAwaiter上。

You seem to be jumping through hoops in order to make NavigateAsync return a Task. But it doesn't have to return a Task in order to be awaitable! A method that contains an await must return Task, but a method that is awaitable need not return Task; all it has to do is return some type that you can call GetAwaiter on.

您可能会考虑实施的小类型是这样的:

You might consider implementing a little type like this:

public struct WebBrowserAwaiter<T>
{
    public bool IsCompleted { get { ... } }
    public void OnCompleted(Action continuation) { ... }
    public T GetResult() { ... }
}

和已经NavigateAsync返回某种类型时,您可以拨打GetAwaiter返回一个WebBrowserAwaiter。没有必要建立一个任务只是为了得到它GetAwaiter方法​​时,你可以使自己的。

and have NavigateAsync return some type upon which you can call GetAwaiter that returns a WebBrowserAwaiter. No need to build up a Task just to get its GetAwaiter method when you can make your own.

更普遍的,有些东西你可能要考虑一下是的如果有就NavigateAsync第二个电话会发生什么,而第一个是依旧导航?

More generally, something you might want to give some thought to is what happens if there is a second call to NavigateAsync while the first one is still navigating?

这篇关于异步/等待实现web浏览器类的.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆