Sea*_*n S 14 .net c# browser asynchronous async-await
长期读者,这里的第一次海报.
我的目标:在使用WebBrowser类时能够利用async/await.由于WebBrowser.Navigate(string url)是一个异步方法,因此在触发LoadComplete事件之前无法检查html文档.
到目前为止,这是我的(工作)代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这个上一课现在允许我使用以下内容:
public async void NavigateToGoogle() {
await browser.NavigateAsync("www.google.com");
//Do any necessary actions on google.com
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否有更有效/正确的方法来处理这个问题.具体来说,Task.Factory.CreateNew具有阻塞ManualResetEvent.感谢您的输入!
Eri*_*ert 12
首先,我认为这是学习async/await如何工作的一个很好的练习.
您似乎正在跳过箍,以使NavigateAsync返回任务.但它不必返回任务以便等待!该方法包含的await必须返回任务,但一个方法是awaitable不用返回任务; 它所要做的就是返回一些你可以调用GetAwaiter的类型.
你可以考虑实现这样的小类:
public struct WebBrowserAwaiter<T>
{
public bool IsCompleted { get { ... } }
public void OnCompleted(Action continuation) { ... }
public T GetResult() { ... }
}
Run Code Online (Sandbox Code Playgroud)
并让NavigateAsync返回一些类型,您可以在其上调用返回WebBrowserAwaiter的GetAwaiter.当你可以创建自己的GetAwaiter方法时,不需要构建一个Task来获取它.
更一般地说,您可能想要考虑的事情是,如果在第一次仍然导航时第二次调用NavigateAsync会发生什么?
| 归档时间: |
|
| 查看次数: |
10682 次 |
| 最近记录: |