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

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

问题描述

长期读者,第一次在这里发帖.

Longtime reader, first-time poster here.

我的目标:能够在使用 WebBrowser 类时利用 async/await.由于 WebBrowser.Navigate(string url) 是一种异步方法,在 LoadComplete 事件被触发之前,您无法检查 html 文档.

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.

这是我目前的(工作)代码:

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();
    }
}

上一个类现在允许我使用以下内容:

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
}

但是,我想知道是否有更有效/更正确的方法来处理这个问题.具体来说,带有阻塞 ManualResetEvent 的 Task.Factory.CreateNew.感谢您的投入!

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!

推荐答案

首先,我认为这是学习 async/await 工作原理的绝佳练习.

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

为了让 NavigateAsync 返回一个任务,您似乎在跳槽.但是它不必为了等待而返回一个 Task !包含await的方法必须返回Task,但可等待的方法不需要返回Task;它所要做的就是返回一些可以调用 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 返回某种类型,您可以根据该类型调用返回 WebBrowserAwaiter 的 GetAwaiter.当您可以创建自己的方法时,无需构建 Task 来获取其 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?

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

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