在静态方法中我使用 WebBrowser。我正在通过匿名方法订阅其 Navigated 事件。我可以指示我的方法仅在 WebBroswer 触发 Navigated 事件并且我的匿名处理程序完成后才返回吗?
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
this 方法以避免任何 UI 线程阻塞并获取返回值。
string proxy = await MyClass.GetProxy();
请注意,包含 await
的方法必须标记为 async
。
关于c# - 指示方法仅在匿名事件处理程序完成后返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33177538/