2011-07-22 4 views
0

バックグラウンドワーカーで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; 
    } 

答えて

0

あなたはあなたの答えhere別の質問が、最終的には同じ問題を見つけることができます。あなたは、列挙子を無効にするforeachループ内のデータを変更しています。
あなたのコード

  • 変更を保存して一覧に作られたとのみ、foreachループの後に一度進捗状況を報告するために必要なすべての変更内容を読んでから、私が見る2つの可能な解決策があります。あなたがバックグラウンドで処理しているので、これは非常に良い解決策ではないかもしれません。グリッド内のデータを変更する可能性のある他のコードが実行されている場合は、同じエラーが再び発生します。
  • 行を追加していないので、foreachをforループに簡単に変更できます。また、メインスレッドのコードが行を追加したり、悪化させたりする場合、問題が発生する可能性があります。
+0

で変化しているDoWorkメソッドで任意のコードがありませんアイテムを追加または削除してコレクションを並べ替えます。 DoWorkが別のスレッドで発生し、コレクションが例外の原因である場合はそのコレクションが別の場所で変更されるため、問題が発生する可能性が高くなります。 – alhalama

+0

http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx「コレクションが変更されない限り、列挙子は有効なままです。コレクションの変更(たとえば、既存のアイテムを変更するとコレクションが無効になり、そのコードはUpdateCacheHostCellのコードとまったく同じです – Eddy

+0

UltraGridRowオブジェクトの同じインスタンスが前後にあるため、コードはコレクションを変更していませんコードが実行されます。 InvalidOperationExceptionをスローするには、コレクション内の項目のインスタンスを追加、削除、または変更する必要があります。リスト内のオブジェクトによって公開されているプロパティの値を変更しても、この例外は発生せず、コードで実行されていることになります。 – alhalama

0

何かのような音は列挙型を無効にする必要があります。

.ToList()を使用して列挙型をリストに変換すると(列挙型が反復され、元のアイテムを含む新しいリストが表示されます)、この新しい列挙型とソースの変更を繰り返し処理できますあなたに影響することはありません。

foreach (UltraGridRow row in uGridCache.Rows.ToList()) 
{ 
    .... 
    workerThread.ReportProgress(0, rowValues); 
} 

あなたが何か他のものは、グリッド上の行を変更している場合は、あなたのReportProgressはもはやグリッド内に存在する何かの進捗状況を報告するかもしれないことを認識する必要があります、あなたはReportProgressハンドラでチェックすることをお勧めしますあなたがしていることをする前に、そのアイテムの進捗状況についての報告がまだ有効かどうか。

0

DoWorkに関するMSDNのドキュメントでは、次のように記載しています。 "DoWorkイベントハンドラのユーザーインターフェイスオブジェクトを操作しないで、BackgroundWorkerイベントを通じてユーザーインターフェイスに通信する必要があります。あなたがここにDoWork方法の詳細を表示することができ

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx

をこのイベントからUltraGridRowsへのアクセスは、あなたが別のスレッドからのUltraGridにアクセスさせると、Windowsのコントロールがスレッドセーフではありませんが形成されます。

これは、コントロールのプロパティにアクセスすることに限定されないことに注意してください。 UltraGridがバインドされているデータソースに値を設定する場合は、変更の通知と同じ問題が発生し、バックグラウンドスレッドで通知が行われ、UIはバックグラウンドスレッドから操作されます。実際にWindows上でスレッドセーフされている唯一の少数のメンバーがあること

注コントロールを形成し、これらは、MSDN上のコントロールのためのスレッドの安全性に関するセクションに記載されています。Windowsでのhttp://msdn.microsoft.com/en-us/library/system.windows.forms.control.aspx

安全、簡単なマルチスレッドはフォームそれは古いにもかかわらず、Windowsフォームでのスレッドのための優れたリソースです:

:Windowsのコントロールフォームにスレッドセーフなコールを発信するにも優れたリソース http://msdn.microsoft.com/en-us/library/ms171728.aspx

関連する問題