2013-02-08 84 views
1

我有一個方法,它運行不同的值到數據庫,檢索值並逐行填寫gridview長時間運行的過程中填充gridview(刷新)

每次調用都需要一些時間並凍結,直到進程結束。我喜歡在gridview中顯示值,同時運行方法並且不凍結屏幕。

我嘗試了下面的東西,它仍然凍結屏幕,我看不到在網格上的值,直到過程完成。

我不想使用Application.Doevents它顯示數據在網格中,如果我在循環中使用它。

任何幫助是讚賞

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 

     Dim t = New Threading.Thread(AddressOf MyWork) 
     t.Start() 
End Sub 


Private Sub MyWork() 
     If Me.InvokeRequired Then 
      Me.Invoke(New MethodInvoker(AddressOf DoWork)) 
     End If 
End Sub 

Private Function DoWork() As Boolean 

    For i As Integer = 1 To 1000000 
     FillGrid(i) 
    Next  
End Function 

回答

2

您可以嘗試使用BackgroundWorker類具有ProgressChanged事件允許您在長時間操作過程中提供中間更新用戶界面。在DoWork函數中,您可以多次調用ReportProgress並將任何對象傳遞給ProgressChanged事件以更新UI。

下面是一個簡單的例子來展示這個概念。首先在ToolBox的設計師視圖中添加BackgroundWorker。該實例將顯示在設計器窗口的底部。選擇BackgroundWorker並設置WorkerReportsProgress屬性等於True

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
    BackgroundWorker1.RunWorkerAsync() 
End Sub 

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    Dim list1 As New List(Of String) 
    list1.Add("A") 
    list1.Add("B") 
    list1.Add("C") 
    BackgroundWorker1.ReportProgress("50", list1) 
    Dim list2 As New List(Of String) 
    list2.Add("1") 
    list2.Add("2") 
    list2.Add("3") 
    BackgroundWorker1.ReportProgress("100", list2) 
End Sub 

Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
    Dim myList As List(Of String) 
    myList = e.UserState 
    For Each str As String In myList 
     DataGridView1.Rows.Add(str) 
    Next 
End Sub 

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
    MessageBox.Show("Operation Complete") 
End Sub 

下面是對發生了什麼的說明。在DoWork例程中,您將在separate thread上執行長操作,而不是UI。當您調用ReportProgress函數時,可以將它傳遞給兩個參數:一個百分比和一個對象......第二個參數在這種情況下更重要。在ProgressChanged例程中,您將採用e.UserState中的同一對象,並按照您的需要進行操作。這發生在UI thread,所以你可以從這裏更新你的控制。在操作完成時調用RunWorkerCompleted例程,該例程也在UI thread上運行。重要的是,當您調用ReportProgress函數時,在BackgroundWorkerUI之間執行線程安全切換。

+0

我試過那會帶來'cross thread'錯誤。你有一個想法,我怎麼能從上面的情況轉變爲背景工作者? –

+0

@huMptyduMpty你能告訴我們你做了什麼來得到這個錯誤嗎?你可能在錯誤的方法(線程)中調用UI線程。 – Styxxy

+0

@huMptyduMpty我用一個例子更新了我的答案。 – Mash