ram*_*nik 5 data-binding user-interface multithreading backgroundworker winforms
我正在修改Windows窗体以允许在UI保持响应的同时在后台加载数据.数据需要花费大量时间来检索和绑定.理想情况下,我会在后台执行这两项工作,但是我在后台应该做什么样的UI更新(如在主线程外部),这有些含糊不清.在后台显示数据检索和数据绑定的一个可靠示例将非常有用.
检索可以而且应该被推送到后台线程 - 但是有一些模式可以将它们全部放在适当位置.
基本上你会启动一个后台线程来检索数据,一旦完成它就需要合并回UI线程来进行实际的UI更新(跨线程的UI更新是坏的坏事).
您可以通过三种基本的背景线程方式进行探索
我个人倾向于代表选项; 一旦你获得模式,它们就很容易使用.BackgroundWorker在前面看起来不错,但有一些问题和缺少的管道,使得它比你期望的更麻烦.让我简单介绍一下代表方法的样本; 我马上就会更新......
编辑
这里有一些代码,它在VB中,但如果你是C#家伙,应该很容易转录.关于你希望后台线程的行为方式你还有几个选项,所以这里有两个示例.非阻塞是我的首选,但如果您将其融入现有代码中,那么阻止对您来说可能更容易.
非阻塞,一旦后台线程完成,将在UI线程上调用回调方法(GetData_Complete)
Sub Main()
Console.WriteLine("On the main thread")
Dim dataDelegate As New GetDataCaller(AddressOf GetData)
Dim iar As IAsyncResult
' Non-blocking approach using a callback method
iar = dataDelegate.BeginInvoke(AddressOf GetData_Complete, Nothing)
End Sub
Private Delegate Sub GetData_CompleteCaller(ByVal iar As IAsyncResult)
Private Sub GetData_Complete(ByVal iar As IAsyncResult)
If InvokeRequired Then
Dim invokeDelegate As New GetData_CompleteCaller(AddressOf GetData_Complete)
Invoke(invokeDelegate, New Object() {iar})
Exit Sub
End If
' Downcast the IAsyncResult to an AsyncResult -- it's safe and provides extra methods
Dim ar As System.Runtime.Remoting.Messaging.AsyncResult = DirectCast(iar, System.Runtime.Remoting.Messaging.AsyncResult)
Dim dataDelegate As GetDataCaller = DirectCast(ar.AsyncDelegate, GetDataCaller)
Dim result As String = dataDelegate.EndInvoke(iar)
Console.WriteLine("On the main thread again, background result is: " + result)
End Sub
Private Delegate Function GetDataCaller() As String
Private Function GetData() As String
Console.WriteLine("On the background thread!")
For index As Integer = 0 To 2
Console.WriteLine("Background thread is working")
Next
Return "Yay, background thread got the data!"
End Function
Run Code Online (Sandbox Code Playgroud)
阻止 子主()
Console.WriteLine("On the main thread")
Dim dataDelegate As New GetDataCaller(AddressOf GetData)
Dim iar As IAsyncResult
' blocking approach; WaitOne() will block this thread from proceeding until the background thread is finished
iar = dataDelegate.BeginInvoke(Nothing, Nothing)
iar.AsyncWaitHandle.WaitOne()
Dim result As String = dataDelegate.EndInvoke(iar)
Console.WriteLine("On the main thread again, background result is: " + result)
End Sub
Private Sub GetData_Complete(ByVal iar As IAsyncResult)
' Downcast the IAsyncResult to an AsyncResult -- it's safe and provides extra methods
Dim ar As System.Runtime.Remoting.Messaging.AsyncResult = DirectCast(iar, System.Runtime.Remoting.Messaging.AsyncResult)
Dim dataDelegate As GetDataCaller = DirectCast(ar.AsyncDelegate, GetDataCaller)
Dim result As String = dataDelegate.EndInvoke(iar)
Console.WriteLine("On the main thread again, background result is: " + result)
End Sub
Private Delegate Function GetDataCaller() As String
Private Function GetData() As String
Console.WriteLine("On the background thread!")
For index As Integer = 0 To 2
Console.WriteLine("Background thread is working")
Next
Return "Yay, background thread got the data!"
End Function
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1122 次 |
| 最近记录: |