Getting web page after calling DownloadStringAsync

2019-06-03 16:12发布

问题:

I don't know enough about VB.Net yet to use the richer HttpWebRequest class, so I figured I'd use the simpler WebClient class to download web pages asynchronously (to avoid freezing the UI).

However, how can the asynchronous event handler actually return the web page to the calling routine?

Imports System.Net

Public Class Form1
    Private Shared Sub DownloadStringCallback2(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
        If e.Cancelled = False AndAlso e.Error Is Nothing Then
            Dim textString As String = CStr(e.Result)

            'HERE : How to return textString to the calling routine?
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim client As WebClient = New WebClient()

        AddHandler client.DownloadStringCompleted, AddressOf DownloadStringCallback2
        Dim uri As Uri = New Uri("http://www.google.com")

        client.DownloadStringAsync(uri)

        'HERE : how to get web page back from callback function?
    End Sub
End Class

Thank you.


Edit: I added a global, shared variable and a While/DoEvents/EndWhile, but there's got to be a cleaner way to do this :-/

Public Class Form1
    Shared page As String

    Public Shared Sub AlertStringDownloaded(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
        '  If the string request went as planned and wasn't cancelled:
        If e.Cancelled = False AndAlso e.Error Is Nothing Then
            page = CStr(e.Result)
        End If
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim wc As New WebClient

        AddHandler wc.DownloadStringCompleted, AddressOf AlertStringDownloaded

        page = Nothing
        wc.DownloadStringAsync(New Uri("http://www.google.com"))
        'Better way to wait until page has been filled?
        While page Is Nothing
            Application.DoEvents()
        End While
        RichTextBox1.Text = page
    End Sub
End Class

回答1:

You can set the RichTextBox1.Text directly in the completed handler if you make the handler function an instance method instead of shared.

Public Class Form1

    Private Sub AlertStringDownloaded(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
        '  If the string request went as planned and wasn't cancelled:
        If e.Cancelled = False AndAlso e.Error Is Nothing Then
            RichTextBox1.Text = CStr(e.Result)
        End If
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim wc As New WebClient

        AddHandler wc.DownloadStringCompleted, AddressOf AlertStringDownloaded

        page = Nothing
        wc.DownloadStringAsync(New Uri("http://www.google.com"))
    End Sub
End Class


回答2:

You haven't found a clean way. Close your form while the download is taking place and behold the kaboom you'll get. You'll have to at least set the form's Enabled property to False.

Look at the BackgroundWorker class to do this cleanly.