2016-12-18 66 views
0

私はいくつかの助けが必要です。 私はBindingListにバインドされた読み取り専用のDataGridViewを持っています。 私は最初に新しいリストのデータソースを設定し、そのリストにアイテムを追加します。 列は自動的に生成されます。 ページをリロードする必要があるときは、リストをクリアして項目をもう一度追加します。BindingList.Clearが実行すると、DataGridViewが発生します。System.IndexOutOfRangeException

私はそれが正常に動作しますが、私はタスクを開始し、するBindingListにクリア()を呼び出し、それを行う場合は例外で失敗UIでページ同期のリロードを実行した場合:

System.IndexOutOfRangeException was unhandled 
    HResult=-2146233080 
    Message=Index 0 does not have a value. 
    Source=System.Windows.Forms 
    StackTrace: 
     at System.Windows.Forms.CurrencyManager.get_Item(Int32 index) 
     at InCare.UserControls.DataGridViewItemWrapper.DataGridViewOnRowsAdded(Object sender, DataGridViewRowPostPaintEventArgs args) in C:\ws\Source\Repos\incare\Src\InCare.UserControls\DataGridViewItemWrapper.cs:line 40 
     at System.Windows.Forms.DataGridViewRowPostPaintEventHandler.Invoke(Object sender, DataGridViewRowPostPaintEventArgs e) 
     at System.Windows.Forms.DataGridView.OnRowPostPaint(DataGridViewRowPostPaintEventArgs e) 
     at System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded) 
     at System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded) 
     at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e) 
     at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) 
     at System.Windows.Forms.Control.WmPaint(Message& m) 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
+0

'BindingList'はスレッドセーフではありません。それが失敗する理由です。 –

答えて

2

はこれがありますマルチスレッドの問題。

BindingListはスレッドセーフではありません。ワーカースレッドで動作するタスクからクリアしようとすると、DGVはUIスレッドからそれを読み取ろうとします。

あなたはコードを投稿しませんでしたが、基本的なアプローチは、タスク内にいくつかのコレクションを構築し、このコレクションを返してBindingListコンテンツを置き換えます。

は、バックグラウンドスレッドからBindingListを変更しようとしないでください

private async Task<IList<SomeDataItem> GetDataItemsAsync() 
{ 
    // do some work in background, e.g. call web service or database 
    // ... 
    return dataItems; 
} 

pirvate async void HandleRefreshButtonClick(object sender, EventArgs e) 
{ 
    var dataItems = await GetDataItemsAsync(); 

    // since we didn't call ConfigureAwait(false) for task, 
    // the rest of method will run on UI thread 
    bindingList.Clear(); 

    foreach (var item in dataItems) 
    { 
     bindingList.Add(item); 
    } 
} 
+0

Async MVVMは正常に動作しません:(。 –

+0

なぜそう思うのですか?MVVMや同様のパターンで非同期を使用するのは良いですが、スレッド間の操作に注意してください。ワーカースレッドからのデータバインドコレクションタスクがWebサービスなどからコレクションをフェッチする場合、各項目のバインドされたコントロールを再描画するだけでは効率的ではありません。 – Dennis

関連する問題