2011-09-03 12 views
5

Oye, tengo un UserControl que siguió bloqueando mi Visual Studio. Entonces me encontré otra instancia de VS y depurando la otra VS y esto es lo que me imaginé:¡Fallas de Visual Studio! - La colección se modificó después de que se creó una instancia del enumerador.

Collection was modified after the enumerator was instantiated. 

Aquí es mi matriz:

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 
    }; 

Y aquí es mi bucle que se estrella contra las Bussines

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); 
     } 
    } 

la línea que se bloquea el diseñador de Visual Studio es this.BackColor = colors[i];

Aquí está la imagen de los subprocesos que se ejecutan:

Threads

Todas las roscas se detuvieron en la misma línea ... this.BackColor = colors[i];

Aquí es el EventViewer registro accidente:

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() 

Esto es lo más extraño que he encontrado hasta ahora. Ayuda que se debe aplicar.

Respuesta

3

Como descubriste, tu código está bloqueando al diseñador, derribando a VS. El problema es que inicia un hilo en el modo de diseño, provocado por el diseñador que ejecuta parte de su código en tiempo de diseño. Por ejemplo, ejecutará el constructor, el evento Load, OnHandleCreated, etcétera. Eso lo convierte en una experiencia de tiempo de diseño muy agradable, su control se verá igual que en el tiempo de ejecución.

Pero eso también puede causar muchos problemas. Debe evitar ejecutar código que puede causar una excepción cuando se ejecuta en un contexto de ejecución diferente. Los ejemplos clásicos intentan abrir un archivo sin especificar la ruta completa, abriendo una conexión dbase con el servidor dbase fuera de línea o inalcanzable. Y definitivamente, al iniciar un hilo, InvokeRequired no funcionará de manera confiable ya que el diseñador construye y destruye el identificador de ventana nativo. La solución es simple:

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

Tendrá que hacer más trabajo, este código tampoco funcionará bien en el tiempo de ejecución. El código enhebrado se bombardeará cuando se cierre la forma en que se coloca el control del usuario. Una vez que lo solucione, las probabilidades son buenas de que ahora también funcione correctamente en tiempo de diseño. Pero no lo hagas

+0

Estuviste cerca: P colocando la creación del hilo en! El cuartel DesignMode no fue lo único que también coloqué en el bucle While y funcionó :) ¡Tx! – Danpe

0

¿Está modificando la colección con cualquier otro código? Por lo general, esto sucede cuando enumera una colección en un bucle e intenta modificar la colección.

+0

No, no estoy modificando nada ... solo tengo pocos UserControls ejecutando algunos hilos, ¿tal vez es algo con los hilos? – Danpe

Cuestiones relacionadas