我有一个自定义对象(MyObject),它实现了 INotifyPropertyChanged 并具有三个属性(一个 int、一个 string 和一个 bool)。这是该对象的代码:
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;
}
}
长话短说,我将这些对象的 BindingList 连接到 DataGridView,如下所示:
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;
}
}
如您所见,当我以编程方式更改我的基础对象列表时(就像我将它们全部设置为 string.Empty 时所做的那样),我使用它来直观地指示 DataGridView 中已更改的行。当我“删除”所有对象时,这确实会增加一些开销,但即使没有这个事件处理程序,它仍然是一个冗长的操作。
最后,我的 WinForms 应用程序目前是单线程的,但我计划编写多线程代码,这样做是有意义的。此操作可能是其中一种情况,但在我走这条路之前,还有什么我遗漏的(或做我不需要做的事情)可以提高此操作的性能,所以它不会几乎需要一分钟才能完成?或者这只是处理 100,000 个对象的本质?