如何在函数内等待事件?

How to wait for the event inside a function?

我正在尝试在 VB.Net WPF 应用程序中编写一个函数,用于在 MS WebBrowser 控件中检索文档的高度。只有在页面呈现后一段时间后,我才能获得此值。所以,我尝试了:

Private Function GetHeight(ByVal htmlstring As String) As Integer
    Dim wb As New WebBrowser 'Declare WebBrowser
    wb.Width = 940 'set Width
    wb.NavigateToString(htmlstring) 'Navigate to content
    Do Until wb.IsLoaded 'Wait until page is rendered

    Loop
    'Get DOM Document
    Dim doc As mshtml.HTMLDocument = wb.Document
    'Get sought value
    Dim RetVal As Integer = CInt(doc.body.getAttribute("scrollHeight").ToString)
    doc = Nothing : wb.Dispose() : wb = Nothing 'Free variables
    Return RetVal 'Return value
End Function

但是调用这样的函数会导致应用程序冻结。我应该怎么办?我是否需要实现 Async 和 Await 关键字以及 Threading.Tasks 以及如何实现?

根据 MSDN,IsLoaded 是一个框架元素 属性,它指示控件是否已加载用于显示,不是WebBrowser 控件的网页是否已加载已加载。

虽然我质疑您为什么要实例化一个浏览器并让它在一个名为 "GetHeight" 的方法中导航到一个页面...我认为您想在这里做的是订阅 LoadCompleted 事件:https://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.loadcompleted(v=vs.110).aspx

也许您可以构建您的网络浏览器并让它以不同的方法导航,然后使用您的 GetHeight 方法订阅 LoadCompleted 事件?

编辑 我忽略了因为你在 xaml 之外声明了你的浏览器控件,控件将永远不会被加载(因此,导航将不起作用) 因为它不在 WPF 应用程序的可视化树中。您必须使用已经在 xaml 中声明的网络浏览器(我会推荐),或者使用如下内容以编程方式添加它:

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="MainPanel">
    <Button Click="Button_Click"> Clicky</Button>
</StackPanel>

Class 主窗口

Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    Dim wb As New WebBrowser 'Declare WebBrowser
    wb.Width = 940 'set Width
    Me.MainPanel.Children.Add(wb)
    wb.NavigateToString("www.whosebug.com")

    AddHandler wb.LoadCompleted, Sub(s, ee) DoSomething()
End Sub

Private Sub DoSomething()
    MessageBox.Show("blah")
End Sub

结束Class