指示方法仅在匿名事件处理程序完成后返回

本文关键字:程序 返回 事件处理 方法 指示 | 更新日期: 2023-09-27 18:17:59

在静态方法中我使用WebBrowser。我为它的Navigated事件订阅了一个匿名方法。我可以指示我的方法只在webbrowser触发导航事件和我的匿名处理程序完成后返回吗?

using forms = System.Windows.Forms;
namespace ProxyProvider
{
    public delegate string finished();
    public static class ProxyProvider
    {
        public static string GetProxy()
        {
            string returnValue = "";
            finished meFinished = () =>
            {
                return returnValue;
            };
            forms.WebBrowser browser = new forms.WebBrowser();
            try
            {
                browser.Navigated += (s, e) =>
                {
                    if (browser.ReadyState == forms.WebBrowserReadyState.Loading) //waiting for browser finishes loading page
                        return;
                    returnValue = ParseHtml(browser.DocumentText); 
                    meFinished();  //I want this function to return only here. After it finishes parsing
                };
                browser.Navigate("http://example.com/proxy-list/");
                return returnValue;  // don't want to return it here
            }
            catch (Exception e)
            {
                forms.MessageBox.Show("ProxyProvider.GetProxy(): " + e.Message);
                return "";
            }
        }
}
}

指示方法仅在匿名事件处理程序完成后返回

可以,但是你需要调整一些东西。

这里的基本概念是,主方法将阻塞,直到从事件处理程序设置了一个值。因为你现在在UI线程上,你会希望这是异步完成的(所以你的窗口保持响应)。

首先我们需要改变你的方法的签名:

public static Task<string> GetProxy()

我们将在这里返回一个Task对象,以便调用者可以等待我们并获得字符串返回值。然后您需要设置一个TaskCompletionSource并在处理程序中设置它:

TaskCompletionSource<string> navTaskSource= new TaksCompletionSource<string>();
browser.Navigated += (s, e) =>
{
     if (browser.ReadyState == forms.WebBrowserReadyState.Loading)
          return;
     string returnValue = ParseHtml(browser.DocumentText); 
     navTaskSource.TrySetResult(returnValue);
};

现在您已经完成了,只需返回任务:

browser.Navigate("http://example.com/proxy-list/");
return navTaskSource.Task;

你的调用代码应该await 这个方法,以避免任何UI线程阻塞,并获得返回值。

string proxy = await MyClass.GetProxy();

包含await的方法必须标记为async