我正在研究冠狀病毒統計儀表板作為大學專案,并且從具有統計資訊的站點下載異步源資料時遇到了一些問題。好吧,我不明白自己該怎么做。
我嘗試使用將創建多個異步 Web 請求的函式創建自己的類,然后等到它們全部完成,然后回傳所有這些請求的結果。
Imports System.Net.WebClient
Imports System.Net
Public Class AsyncDownload
Private result As New Collection
Private Sub DownloadCompletedHander(ByVal sender As Object, ByVal e As System.Net.DownloadStringCompletedEventArgs)
If e.Cancelled = False AndAlso e.Error Is Nothing Then
Dim myString As String = CStr(e.Result)
result.Add(myString, sender.Headers.Item("source"))
End If
End Sub
Public Function Load(sources As Array, keys As Array) As Collection
Dim i = 0
Dim WebClients As New Collection
While (i < sources.Length)
Dim newClient As New WebClient
newClient.Headers.Add("source", keys(i))
newClient.Headers.Add("sourceURL", sources(i))
AddHandler newClient.DownloadStringCompleted, AddressOf DownloadCompletedHander
WebClients.Add(newClient)
i = i 1
End While
i = 1
For Each client As WebClient In WebClients
Dim url As String = client.Headers.Item("sourceURL")
client.DownloadStringAsync(New Uri(url))
Next
While (result.Count < WebClients.Count)
End While
Return result
End Function
End Class
它用于:
Dim result As New Collection
Private Sub test() Handles Me.Load
Dim downloader As New CoronaStatisticsGetter.AsyncDownload
result = downloader.Load({"https://opendata.digilugu.ee/covid19/vaccination/v3/opendata_covid19_vaccination_total.json"}, {"Nationalwide Data"})
End Sub
它應該像這樣作業:
- 我創建了我的班級的一個新實體。
- 呼叫這個類的函式Load
- Funciton Load 為每個 url 創建 System.Net.WebClient 實體并添加為處理程式 DownloadCompletedHander
- 函式 Load 去呼叫每個客戶端的 DownloadStringAsync
- 函式加載在 While 回圈中等待,直到結果集合項計數不如輸入的 url 數大
- 如果結果中的專案數與 urls 數相同,則表示所有內容都已下載,因此它會中斷回圈并回傳所有請求的資料
問題是它不起作用,它只是無休止地留在 while 回圈中,而且正如我所見,使用除錯收集結果沒有更新(它的大小始終為 0)
同時,當我嘗試在不使用我的類的情況下異步下載它時,一切正常:
Private Sub Download() 'Handles Me.Load
Dim wc As New System.Net.WebClient
wc.Headers.Add("source", "VaccinationByAgeGroup")
AddHandler wc.DownloadStringCompleted, AddressOf DownloadCompletedHander
wc.DownloadStringAsync(New Uri("https://opendata.digilugu.ee/covid19/vaccination/v3/opendata_covid19_vaccination_agegroup.json"))
End Sub
有人可以告訴我為什么它不起作用以及問題出在哪里?
uj5u.com熱心網友回復:
下面展示了如何使用System.Net.WebClient和Task從 URL 下載字串(即:資料)。
添加專案參考(System.Net)
與 2019 年相比:
- 在 VS 選單中,單擊專案
- 選擇添加參考...
- 選擇裝配體
- 檢查System.Net
- 點擊確定
創建一個類(名稱:DownloadedData.vb)
Public Class DownloadedData
Public Property Data As String
Public Property Url As String
End Class
創建一個類(名稱:HelperWebClient.vb)
Public Class HelperWebClient
Public Async Function DownloadDataAsync(urls As List(Of String)) As Task(Of List(Of DownloadedData))
Dim allTasks As List(Of Task) = New List(Of Task)
Dim downloadedDataList As List(Of DownloadedData) = New List(Of DownloadedData)
For i As Integer = 0 To urls.Count - 1
'set value
Dim url As String = urls(i)
Debug.WriteLine(String.Format("[{0}]: Adding {1}", i, url))
Dim t = Task.Run(Async Function()
'create new instance
Dim wc As WebClient = New WebClient()
'await download
Dim result = Await wc.DownloadStringTaskAsync(url)
Debug.WriteLine(url & " download complete")
'ToDo: add desired code
'add
downloadedDataList.Add(New DownloadedData() With {.Url = url, .Data = result})
End Function)
'add
allTasks.Add(t)
Next
For i As Integer = 0 To allTasks.Count - 1
'wait for a task to complete
Dim t = Await Task.WhenAny(allTasks)
'remove from List
allTasks.Remove(t)
'write data to file
'Note: The following is only for testing.
'The index in urls won't necessarily correspond to the filename below
Dim filename As String = System.IO.Path.Combine("C:\Temp", String.Format("CoronavirusData_{0:00}.txt", i))
System.IO.File.WriteAllText(filename, downloadedDataList(i).Data)
Debug.WriteLine($"[{i}]: Filename: {filename}")
Next
Debug.WriteLine("all tasks complete")
Return downloadedDataList
End Function
End Class
Usage:
Private Async Sub btnRun_Click(sender As Object, e As EventArgs) Handles btnRun.Click
Dim helper As HelperWebClient = New HelperWebClient()
Dim urls As List(Of String) = New List(Of String)
urls.Add("https://opendata.digilugu.ee/covid19/vaccination/v3/opendata_covid19_vaccination_total.json")
urls.Add("https://api.covidtracking.com/v2/states.json")
urls.Add("https://covidtrackerapi.bsg.ox.ac.uk/api/v2/stringency/date-range/2020-01-01/2022-03-01")
urls.Add("http://covidsurvey.mit.edu:5000/query?age=20-30&gender=all&country=US&signal=locations_would_attend")
Dim downloadedDataList = Await helper.DownloadDataAsync(urls)
Debug.WriteLine("Complete")
End Sub
Resources:
- How do I wait for something to finish in C#?
- How should Task.Run call an async method in VB.NET?
- VB.net ContinueWith
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/440240.html
標籤:VB.net 异步 下载 httpwebrequest
