我試圖更新背景工作程序中的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