我有工作代码来阅读使用以下内容的RSS源:
Dim doc As New XmlDocument
doc.Load("http://...")
Dim channel As XmlElement = doc("rss")("channel")
Dim items As XmlNodeList = channel.GetElementsByTagName("item")
不幸的是,doc.Load调用会导致程序的其余部分无响应,直到完成。
以异步方式执行加载并具有回调函数来处理数据的最佳方法是什么?
编辑:以下是我尝试使用WebClient的代码 - Load
方法仍然滞后:
Private Sub checkResults()
'request rss feed
Dim w As New System.Net.WebClient
AddHandler w.OpenReadCompleted, AddressOf rssReadCallback
w.OpenReadAsync(New Uri("http://..."))
End Sub
Private Sub rssReadCallback(ByVal sender As Object, ByVal e As System.Net.OpenReadCompletedEventArgs)
Dim reply As Stream = Nothing
Try
reply = CType(e.Result, Stream)
Dim doc As New XmlDocument
doc.Load(reply) ' This line takes forever to complete
Dim channel As XmlElement = doc("rss")("channel")
Dim items As XmlNodeList = channel.GetElementsByTagName("item")
'...
Finally
If Not reply Is Nothing Then
reply.Close()
End If
End Try
调用checkResults后,rssReadCallback方法执行得相当快,但是在Load
方法中UI被冻结。
答案 0 :(得分:4)
我不相信XmlDocument
本身内置了任何异步功能,但您可以轻松地使用线程池(如果您使用的是.NET 4,则使用任务并行库)来加载文档后台线程就像任何其他长时间运行的操作一样。然后,您可以将一个回调编组回UI线程,以便在文档加载时处理该文档。
(如果 使用.NET 4,我强烈建议您使用XDocument
而不是XmlDocument
; LINQ to XML是一个可爱的API。)< / p>
另一个选择是首先使用WebClient
下载文档,然后在内存已加载时加载它 - WebClient
已经支持异步操作,因此您只需添加适当的事件处理程序即可将自动在您的UI线程中执行。
答案 1 :(得分:1)
您可以将其加载到另一个线程中。 Microsoft有一个KB解释如何在Visual Basic .NET中使用线程: