从Task更新Datagridview UI

时间:2014-02-24 08:17:39

标签: vb.net winforms datagridview

我正在开发一个Windows表单应用程序来轮询信息(RFID标签)并在datagridview中显示它们。我还希望用户能够随时启动和停止轮询,因此我使用了一个Task来处理轮询。 由于Task创建了另一个线程,我将主线程的上下文传递给我创建的线程(允许它修改主线程资源和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

2 个答案:

答案 0 :(得分:0)

grdTags.Refresh()只重绘对象但不刷新基础日期(我真的希望他们会对此做些什么,经常发生)。

尝试使用BindingSource代替。另一种解决方案是将datagrid的DataSource设置为null,然后设置为您想要的实际数据源。

我在这里写了https://stackoverflow.com/a/7079829/427684

这个答案

答案 1 :(得分:0)

所以我终于找到了解决方案(我整个周末都在考虑这个问题,就像我发布的那样,半小时后我找到了解决方案:p)

我的解决方案是:     Task.Factory.StartNew(子()               'grdTags.Rows.Clear()               grdTags.DataSource =没什么               'grdTags.DataSource = BindingSource               grdTags.DataSource = lstTags               grdTags.ResetBindings()               grdTags.Refresh()           End Sub,           CancellationToken.None,           TaskCreationOptions.LongRunning,           上下文中)

只需将DataGridView中的DataSource设置为Nothing

即可
grdTags.DataSource = Nothing

然后使用新列表

更新数据源

grdTags.DataSource = lstTags