BindingList<T>导致DataGridView报错

我创建了一个winform应用, 应用里有DataGridView,用BindingList做数据源.

MotionList = new List<Motion>();
MotionBList = new BindingList<Motion>(MotionList);
DataGridViewMotion.DataSource = MotionBList;
DataGridViewMotion.RowHeadersVisible = false;
DataGridViewMotion.AllowUserToAddRows = false;
DataGridViewMotion.ReadOnly = true;

Motion的定义如下

public class Motion
{
    public string StartPos { get; set; }
    public string EndPos { get; set; }
}

我用 MotionBList.Add() MotionBList.RemoveAt() 这两方法来更新DataGridViewMotion。 大部分时候都没问题,都正常。有几条线程更新MotionBList,但是都用的是SyncContext在UI线程上执行。

SyncContext = WindowsFormsSynchronizationContext.Current;

SyncContext.Post(new SendOrPostCallback((_) =>
{
    if (MotionBList.Count > 600)
    {
        for (int i = 0; i < 100; i++)
        {
             MotionBList.RemoveAt(0);
        }
    }
    MotionBList.Add(MakeMotion(...));
}), null);

private Motion MakeMotion(string a, string b)
{
    return new Motion() {StartPos = a, EndPos = b};
}

但是有很小的概率,在用 MotionBList.Add(new Motion(...)) 时会报异常, 异常的信息如下:

Application_ThreadException System.ArgumentOutOfRangeException:107 的值对于 indexStart 无效, indexStart 必须小于或等于 93.
Application_ThreadException System.ArgumentOutOfRangeException: 1270 的值对于 indexStart 无效, indexStart 必须小于或等于 598.
在 System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter)
在 System.Windows.Forms.DataGridViewRowCollection.GetPreviousRow(Int32 indexStart, DataGridViewElementStates includeFilter, DataGridViewElementStates excludeFilter)
在 System.Windows.Forms.DataGridView.CorrectRowFrozenState(DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Index32 anticiptedRowIndex)
在 System.Windows.Forms.DataGridView.OnInsertingRow(Int32 rowIndexInserted, DataGridViewRow dataGridViewRow, DataGridViewElementStates rowState, Point& newCurrentCell, Boolean firstInsertion, Int32 insertionCount, Boolean force)
在 System.Windows.Forms.DataGridViewRowCollection.InsertInternal(Int32 rowIndex, DataGridViewRow dataGridViewRow, Boolean force)
在 System.Windows.Forms.DataGridViewRowDataCollection.ProcessListChanged(ListChangedEventArgs e)
在 System.Windows.Forms.DataGridViewRowDataCollection.currencyManager_ListChanged(Object sender, ListChangedEventArgs e)
在 System.Windows.Forms.CurrencyManager.OnListChanged(ListChangedEventArgs e)
在 System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
在 System.ComponentModel.BindingList'1.OnListChanged(ListChangedEventArgs e)
在 System.ComponentModel.BindingList'1.FireListChanged(ListChangedType type, Int32 index)
在 System.ComponentModel.BindingList'1.InsertItem(Int32 index, T item)
在 System.Collections.ObjectModel.Collection'1.Add(T item)
在 MotionBList.Add(MakeMotion(...))

然后其他很多控件上就出现红叉叉, 上面的异常信息是Programe.cs里的代码捕获到的

Application.ThreadException += Application_ThreadException;
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
   MessageBox.Show($"Application_ThreadException {e.Exception}");
}

异常信息的MessageBox,图里报出错误的825那一行,就是一句 MotionBList.Add(MakeMotion(...))
img

Application_ThreadException System.ArgumentOutOfRangeException: The
107 的值对于 indexStart 无效, indexStart 必须小于或等于 93. 
Application_ThreadException
System.ArgumentOutOfRangeException: 1270 的值对于
indexStart 无效, indexStart 必须小于或等于 598.

你的这个错误信息,怎么看到是多线程操作,出现的问题,多线程访问同一个数据,并进行修改,造成了线程不安全