我有一个实现INotifyPropertyChanged并具有三个属性(一个int,一个字符串和一个布尔)的自定义对象(MyObject)。下面是这个对象的代码:修改绑定到DataGridView的大型数据集需要很长时间?
public class MyObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
private int _Index;
public int Index
{
get { return _Index; }
set
{
if (_Index == value)
{
return;
}
_Index = value;
OnPropertyChanged(new PropertyChangedEventArgs("Index"));
}
}
private string _Name;
public string Name
{
get { return _Name; }
set
{
if (_Name == value)
{
return;
}
_Name = value;
_Modified = true;
OnPropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
private bool _Modified;
public bool Modified
{
get { return _Modified; }
set
{
if (_Modified == value)
{
return;
}
_Modified = value;
OnPropertyChanged(new PropertyChangedEventArgs("Modified"));
}
}
public MyObject()
{
}
public MyObject(int index, string number, bool modified)
{
Index = index;
Number = number;
Modified = modified;
}
}
要长话短说,我有这些对象迷上了一个DataGridView这样的一个的BindingList:
BindingList<MyObject> myObjectList = new BindingList<MyObject>();
BindingSource bindingSourceForMyObjects = new BindingSource();
bindingSourceForMyObjects.DataSource = myObjectList;
dataGridViewMyObjects.DataSource = bindingSourceForMyObjects;
当我的应用程序运行时,myObjectList会填充100,000个对象(从文件中读取)并显示在我的DataGridView中。我只在DataGridView中有一列显示我的对象的字符串属性。有可能我的用户可能想要选择DataGridView中的所有行并“删除”它们。我在术语删除时使用了引号,因为对象实际上并未被删除,而是所有100,000个对象的字符串属性被设置为string.Empty。现在,我使用此代码执行该操作:
myObjectList.ToList().ForEach(c => c.Name = string.Empty);
操作耗时〜55秒即可完成。我也试过:
foreach (DataGridViewRow row in dataGridViewMyObjects.SelectedRows)
{
row.Cells["NAME"].Value = string.Empty;
}
这需要稍少的时间为49秒,但它仍然是一个长时间操作。在一个侧面说明,我也有这样的bindingSourceForMyObjects定义的ListChanged事件处理程序:
private void bindingSourceForMyObjects_ListChanged(object sender, ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemChanged)
{
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.BackColor = Color.Red;
dataGridViewMyObjects.Rows[e.NewIndex].DefaultCellStyle.ForeColor = Color.White;
}
}
正如你所看到的,我使用这个在视觉上指示已在DataGridView被改变,当我编程一行改变我的底层对象列表(就像我将它们全部设置为string.Empty时一样)。当我“删除”所有的对象时,这确实增加了一些开销,但即使没有这个事件处理器,它仍然是一个漫长的操作。
最后,我的WinForms应用程序目前是单线程的,但我计划使用多线程代码,这样做有意义。这个操作可能是其中一种情况,但在我走下那条路之前,还有什么我错过的(或者我不需要这样做),这会提高这个操作的性能,花费近一分钟才能完成?或者,这只是处理100,000个物体的性质?
你能打破在'.ToList()花费的时间'VS中花费的时间' .ForEach(c => ...)'? –
也'c.Name'属性在其setter中做任何事情或只是一个自动属性? –
.ToList()需要<.005秒。剩下的时间用在.ForEach()中。关于c.Name,除了赋值之外,它的唯一一件事是将对象的bool属性设置为true(我使用bool属性来跟踪哪些对象是脏的并且需要刷新到磁盘)。 – user685869