2011-09-03 23 views
5

ちょっと、私のVisual StudioがクラッシュしてしまったUserControlがあります。 だから私はVSの別のインスタンスを実行し、他のVSをデバッグし、これは私が考え出しものです:ここでは Visual Studioがクラッシュします。 - 列挙子がインスタンス化された後にコレクションが変更されました

Collection was modified after the enumerator was instantiated. 

は私の配列です:

private static Color[] colors = 
    { 
     Color.FromArgb(155, 188, 255), // 40000 
     Color.FromArgb(156, 189, 255), // 39500 
     Color.FromArgb(157, 188, 255), // 39000 
     Color.FromArgb(156, 189, 254), // 38500 
    }; 

そして、ここでタマンをクラッシュし、私のループである

Visual Studioのデザイナがクラッシュ
public Heater() 
    { 
     InitializeComponent(); 
     this.tarTemp = this.curTemp; 
     new Thread(() => UpdateTemp(true)).Start(); 
    } 

    private delegate void UpdateTempDelegate(bool loop); 
    private void UpdateTemp(bool loop) 
    { 
     if (lblTemp.InvokeRequired) 
     { 
      UpdateTempDelegate del = new UpdateTempDelegate(UpdateTemp); 
      lblTemp.Invoke(del, loop); 
     } 
     else 
     { 
      do 
      { 
       lblTemp.Text = curTemp + C; 
       if (curTemp >= 0) 
       { 
        int i = curTemp - 10; 
        if (i < 0) 
         i = 0; 
        if (i > colors.Length - 1) 
         i = colors.Length - 1; 
        this.BackColor = colors[i]; // I'M CRASHING !!! 
       } 
      } while (loop && !this.Disposing); 
     } 
    } 

ラインはthis.BackColor = colors[i];

です

Application: devenv.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.InvalidOperationException 
Stack: 
    at System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource) 
    at System.Collections.Generic.SortedList`2+SortedListValueEnumerator[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MoveNext() 
    at Microsoft.VisualStudio.Shell.ServiceProviderHierarchy.GetService(System.Type) 
    at System.ComponentModel.Design.ServiceContainer.GetService(System.Type) 
    at System.ComponentModel.Design.DesignerHost.GetService(System.Type) 
    at System.ComponentModel.Design.DesignerHost+Site.System.IServiceProvider.GetService(System.Type) 
    at System.Windows.Forms.Control.get_AmbientPropertiesService() 
    at System.Windows.Forms.Control.get_BackColor() 
    at System.Windows.Forms.Control.set_BackColor(System.Drawing.Color) 
    at Multiplier.Heater.UpdateTemp(Boolean) 
    at Multiplier.Heater.<.ctor>b__0() 
    at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
    at System.Threading.ThreadHelper.ThreadStart() 

すべてのスレッドが同じライン上に停止しThreads

...ここ

this.BackColor = colors[i];EventViewerクラッシュログがある:ここ

は、実行中のスレッドの画像です

これは私が今までに遭遇した最も奇妙なことです。 ヘルプはうまくいくはずです。

答えて

3

あなたが知ったように、あなたのコードはデザイナーをクラッシュさせ、VSを落としてしまいます。問題は、設計時にデザイナーがコードの一部を実行することによってトリガーされるデザインモードでスレッドを開始することです。たとえば、コンストラクター、Loadイベント、OnHandleCreatedなどが実行されます。これは非常に素晴らしい設計時の経験をもたらします。あなたのコントロールは、実行時と同じように見えます。

しかし、これも多くの問題を引き起こす可能性があります。異なる実行コンテキストで実行されるときに例外を引き起こす可能性があるコードを実行しないようにする必要があります。古典的な例では、フルパスを指定せずにファイルをオープンしようとしていますが、dbaseサーバーとのdbase接続をオフラインまたは到達不能にしています。そして、スレッドを確実に開始するには、InvokeRequiredは、デザイナーがネイティブウィンドウハンドルを作成して破棄するため、確実に動作することはありません。修正は簡単です:

public Heater() 
{ 
    InitializeComponent(); 
    this.tarTemp = this.curTemp; 
    if (!this.DesignMode) { 
     new Thread(() => UpdateTemp(true)).Start(); 
    } 
} 

このコードは実行時にうまくいくわけではありません。ユーザーコントロールが置かれているフォームが閉じられると、スレッドコードが爆発します。いったんそれを修正すれば、設計時に正しく機能するようになります。しかし、しないでください。

+0

あなたは近くにいました:Pは!DesignModeのバラックにスレッドの作成を配置することは、私もWhileループを配置しただけではありませんでした:) Thx! – Danpe

0

他のコードを使用してコレクションを変更していますか?通常、これはループ内のコレクションを列挙してコレクションを変更しようとするときに発生します。

+0

何も変更していません...私はいくつかのスレッドを実行しているUserControlsはほとんどありません。 – Danpe

関連する問題