2014-02-24 81 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