UI 以外の作業を同じスレッドで行う場合 (この場合は、ストリームと画像を操作する場合)、UI が遅くなることを想定する必要があります。解決策は、UI スレッドをユーザーに任せて、この作業を別のスレッドにオフロードすることです。ワーカー スレッドが終了したら、UI スレッドに更新を指示します。
2 番目のポイントは、ListView データをバッチで更新する場合、すべての操作が完了するまで ListView に待機するように指示する必要があるということです。
こうすればもっといい。解説はインラインです。
// Create a method which will be executed in background thread,
// in order not to block UI
void StartListViewUpdate()
{
// First prepare the data you need to display
List<ListViewItem> newItems = new List<ListViewItem>();
foreach (var dr in Ringscode.Where(S => !S.IsSold))
{
newItems.Insert(0,
new ListViewItem(dr.CodeNo.ToString(), dr.RingID.ToString()));
imgList.Images.Add(dr.RingID.ToString(), binaryToImage(dr.Image));
}
// Tell ListView to execute UpdateListView method on UI thread
// and send needed parameters
listView.BeginInvoke(new UpdateListDelegate(UpdateListView), newItems);
}
// Create delegate definition for methods you need delegates for
public delegate void UpdateListDelegate(List<ListViewItem> newItems);
void UpdateListView(List<ListViewItem> newItems)
{
// Tell ListView not to update until you are finished with updating it's
// data source
listView.BeginUpdate();
// Replace the data
listViewCollection.Clear();
listViewCollection.LargeImageList = imgList;
listViewCollection.LargeImageList.ImageSize = new System.Drawing.Size(100, 100);
foreach (ListViewItem item in newItems)
listViewCollection.Add(item);
// Tell ListView it can now update
listView.EndUpdate();
}
// Somewhere in your code, spin off StartListViewUpdate on another thread
...
ThreadPool.QueueUserWorkItem(new WaitCallback(StartListViewUpdate));
...
私はこれをインラインで書き、VS でテストしていないので、いくつか修正する必要があるかもしれません。