我试图更新背景工作程序中的Ultragridrow单元格,但当这被称为多于1次时,这会引发InvalidOperation异常。试图在后台工作线程中更改值单元格
这里有启动RunWorkerAsync的方法。
private void RefreshGridCacheStart()
{
try
{
if (this.uGridCache.Rows.Count == 0)
{
return;
}
if(!workerThread.IsBusy)
{
workerThread.DoWork += LookUpHostnames;
workerThread.ProgressChanged += UpdateCacheHostCell;
workerThread.RunWorkerCompleted += WorkerCompleted;
workerThread.WorkerReportsProgress = true;
workerThread.RunWorkerAsync();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + "\n" + ex.Source + "\n" + ex.ToString());
}
}
这是DoWork的方法:
private void LookUpHostnames(object sender, DoWorkEventArgs e)
{
var rowValues = new object[2];
try
{
foreach (UltraGridRow row in uGridCache.Rows)//here is were I get an invalid operation exception
{
string cellValue = row.Cells["Host"].Text;
if (Globals.cNet.isValidIP(cellValue))
{
rowValues[0] = row;
rowValues[1] = cellValue;
workerThread.ReportProgress(0, rowValues);
string resolvedHostname = Globals.cIPLookup.LookupHostFromIP(cellValue);
rowValues[1] = resolvedHostname;
workerThread.ReportProgress(0, rowValues);
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + "\n" + ex.Source + "\n" + ex.ToString());
}
}
这是报告进展方法:
private void UpdateCacheHostCell(object sender, ProgressChangedEventArgs e)
{
var rowValues = e.UserState as object[];
var row = (UltraGridRow) rowValues[0];
var sMesage = (string) rowValues[1];
row.Cells["Host"].Value = sMesage;
}
没有在DoWork的方法的任何代码被改变通过添加或删除项目来收集行。发生此问题的可能性更大,因为DoWork发生在另一个线程上,并且集合在别处被修改(如果这是异常的原因)。 – alhalama
请参阅http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx“只要集合保持不变,枚举数仍然有效如果对集合进行了更改(例如添加,修改或删除元素..“更改现有项目也会使集合无效,这正是他的代码在UpdateCacheHostCell中的作用 – Eddy
代码不会修改集合,因为UltraGridRow对象的同一个实例将在集合之前和之后代码被执行。您需要添加,删除或更改集合中的项目实例,以便引发InvalidOperationException。修改列表中的对象公开的属性的值不会导致此异常,这就是代码所做的事情。 – alhalama