DataGridView.RowEnter事件中的Task.WaitAll()导致DataError 参考Async/Await - Best Practices in Asynchronous Programming

我正在使用Advanced DataGridView(https://github.com/davidegironi/advanceddatagridview)在我的应用程序中显示一些数据。

在RowEnter事件中,我创建如下任务:

Dim One As String = dgv.Item("Col1",e.RowIndex)
Dim Two As String = dgv.Item("Col2",e.RowIndex)
Dim Three As String = dgv.Item("Col3",e.RowIndex)

Dim tOne As Task(Of DataTable) = Task.Run(Function() Return GetData(One) End Function)
Dim tTwo As Task(Of DataTable) = Task.Run(Function() Return GetData(Two) End Function)
Dim tThree As Task(Of DataTable) = Task.Run(Function() Return GetData(Three) End Function)

Task.WaitAll(tOne,tTwo,tThree)

'Do stuff with the results of tasks to update other labels etc on the form
lblDate.Text = tOne.Result.Rows(0).Item("Date").ToString

这样做的原因是,如果GetData()函数花费5秒返回而不执行此操作,则将导致15秒的等待时间(5 + 5 + 5),而使用任务仅需5秒秒(或最慢的任务是什么)和Task.WaitAll将控制权交还给UI(不确定正确的术语),因此感觉有点敏捷。

但是,当我应用过滤器时,我反复遇到以下异常,其中[n]是任意数字,我已经看到-1向上的索引(似乎取决于可见行的数量?):>

System.IndexOutOfRangeException: Index [n] does not have a value.
   at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)
   at System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 boundColumnIndex,Int32 columnIndex,Int32 rowIndex)

如果我删除Task.WaitAll()或同步执行功能,则不会出现上述错误。

我完全不知道该错误的根本原因是什么,或者我应该做些什么来避免该错误。

我见过this answer,但不确定如何应用。

chkxchkx 回答:DataGridView.RowEnter事件中的Task.WaitAll()导致DataError 参考Async/Await - Best Practices in Asynchronous Programming

使用异步事件处理程序,然后使用Task.WhenAll

等待任务
' Mark the event handler with Async so you can use Await in it.
Private Async Sub Grid_RowEnter(sender As Object,e As WhateverEventArgs)
    Dim One As String = dgv.Item("Col1",e.RowIndex)
    Dim Two As String = dgv.Item("Col2",e.RowIndex)
    Dim Three As String = dgv.Item("Col3",e.RowIndex)

    Dim tOne As Task(Of DataTable) = Task.Run(Function() Return GetData(One) End Function)
    Dim tTwo As Task(Of DataTable) = Task.Run(Function() Return GetData(Two) End Function)
    Dim tThree As Task(Of DataTable) = Task.Run(Function() Return GetData(Three) End Function)

    ' await all the tasks
    Await Task.WhenAll(tOne,tTwo,tThree)

    ' back on UI thread

    'Do stuff with the results of tasks to update other labels etc on the form
    lblDate.Text = tOne.Result.Rows(0).Item("Date").ToString

End Sub

参考Async/Await - Best Practices in Asynchronous Programming

本文链接:https://www.f2er.com/3152023.html

大家都在问