2014-02-24 79 views
1

我正在開發一個Windows窗體應用程序來輪詢信息(RFID標籤)並在datagridview中顯示它們。我還希望用戶能夠隨時啓動和停止輪詢,因此我使用Task來處理輪詢。 由於任務創建另一個線程,我通過主線程的上下文中,我創建了一個(允許它來修改主線程資源和UI)從任務更新Datagridview UI

我的問題: 第一個調查是正確完成後,任務找到一個TAG,將其插入到我的DataGridView中,UI顯示信息。 但是,當我的輪詢試圖插入新的TAGS時,出現問題,它正確地將它們插入到DataGridView.DataSource中,但它永遠不會更新UI並在DataGridView中顯示新元素。我無法更新數據網格中的新元素。我不能理解第一次正確完成的原因,但是其他時間錯誤。

我的代碼是在這裏:

Dim lstTags As List(Of CustomTag) 
Dim MsSleep As Integer = 1000 
Public primaryTokenSource As CancellationTokenSource 


Private Sub btnStartPolling_Click(sender As System.Object, e As System.EventArgs) Handles btnStartPolling.Click 

    btnStopPolling.Visible = True 
    primaryTokenSource = New CancellationTokenSource() 
    Dim context As TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext() 
    Dim ct As CancellationToken = primaryTokenSource.Token 
    Task.Factory.StartNew(Sub() 
          ct.ThrowIfCancellationRequested() 
          PollRFID(context, ct, MsSleep) 
         End Sub) 
End Sub 
Private Sub PollRFID(context As TaskScheduler, ct As CancellationToken, MsSleep As Integer) 
    Try 
     While True 
      ' Check if the stop button has been pushed 
      If (ct.IsCancellationRequested) Then ct.ThrowIfCancellationRequested() 
      ' Check if we find any new TAG 
      Dim TagID As String = "" 
      ' TagID is read ByRef 
      _reader.ReadRFID(TagID) 
      If TagID <> "" Then 
        ' CustomTag is a class With a string TagID and a Date InsertDate 
        Dim tc As New CustomTag 
        tc.Tag = TagID 
        tc.InsertDate = Now 
        lstTags.Add(tc) 
        Task.Factory.StartNew(Sub() 
              grdTags.DataSource = lstTags 
              grdTags.Refresh() 
           End Sub, 
           CancellationToken.None, 
           TaskCreationOptions.LongRunning, 
           context) 

      End If 
      Thread.Sleep(MsSleep) 
     End While 
    Catch ex As Exception 

    End Try 
End Sub 

Private Sub btnStopPolling_Click(sender As System.Object, e As System.EventArgs) Handles btnStopPolling.Click 
    primaryTokenSource.Cancel() 
    btnStopPolling.Visible = False 
End Sub 

回答

0

所以,我終於找到了一個解決方案(我一直都在週末思考這個問題,只是因爲我張貼,半小時後我找到一個解決方案:p)

我的解決辦法是: Task.Factory.StartNew(子() 'grdTags.Rows.Clear() grdTags.DataSource =無 ' grdTags.DataSource = BindingSource的 grdTags.DataSource = lstTags grdTags.ResetBindings() grdTags.Refresh() 完子, CancellationToken.None, TaskCreationOptions.LongRunning, 上下文)

只需設置DataSource在DataGridView爲Nothing

grdTags.DataSource = Nothing 

,然後更新與該數據源新名單

grdTags.DataSource = lstTags

0

grdTags.Refresh()只重繪對象,但不會刷新基礎日期(我真的希望他們會做一些事,發生如此頻繁)。

嘗試使用BindingSource代替。另一種解決方案是將datagrid的DataSource設置爲null,然後設置爲您想要的實際數據源。

我寫了關於它的這個答案在這裏https://stackoverflow.com/a/7079829/427684

+1

已經嘗試過的BindingSource,並不會工作 – RdPC

+0

然後我會建議將應用程序剝離到可能運行的最小代碼量。從這個工作,希望這應該突出問題。你有沒有嘗試將它設置爲null/nothing,然後將DataSource設置爲你想要的? – Coops

+0

是的,這終於爲我工作,不知道爲什麼,但它沒有 – RdPC