2011-09-03 15 views
5

Ehi, ho un controllo utente che ha interrotto il mio Visual Studio. così mi sono imbattuto un'altra istanza di VS e il debug l'altra VS e questo è quello che ho pensato:Visual Studio si blocca! - La raccolta è stata modificata dopo l'istanziazione dell'enumerazione

Collection was modified after the enumerator was instantiated. 

Qui è la mia matrice:

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

E qui è il mio ciclo che blocca i 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 linea che si blocca la progettazione di Visual Studio è this.BackColor = colors[i];

Qui è l'immagine dei thread in esecuzione:

Threads

Tutti i filetti fermato sulla stessa linea ... this.BackColor = colors[i];

Ecco la EventViewer registro incidente:

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

Questa è la cosa più strana che ho incontrato finora. Aiuto che dovrebbe essere appagato.

risposta

3

Come hai scoperto, il tuo codice sta bloccando il progettista, portando con sé il VS. Il problema è che si avvia una discussione in modalità progettazione, innescata dal progettista che esegue parte del codice in fase di progettazione. Ad esempio, eseguirà il costruttore, l'evento Load, OnHandleCreated, eccetera. Ciò consente un'esperienza di design molto piacevole, il tuo controllo sarà simile a quello di runtime.

Ma questo può anche causare un sacco di problemi. È necessario evitare l'esecuzione di codice che potrebbe causare un'eccezione quando viene eseguito in un contesto di esecuzione diverso. Gli esempi classici stanno tentando di aprire un file senza specificare il percorso completo, aprendo una connessione dbase con il server dbase offline o irraggiungibile. E sicuramente iniziando una discussione, InvokeRequired non funzionerà in modo affidabile mentre il progettista costruisce e distrugge l'handle della finestra nativa. La correzione è semplice:

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

Avrai bisogno di fare più lavoro, questo codice non funzionerà bene in fase di esecuzione. Il codice threadizzato verrà bombardato quando il modulo su cui è posizionato il controllo utente viene chiuso. Una volta sistemato, le probabilità sono buone che ora funzioni correttamente anche in fase di progettazione. Ma non farlo.

+0

Eri vicino: P la creazione di thread nella casetta! DesignMode non è stata l'unica cosa che ho inserito anche nel ciclo While e ha funzionato :) Thx! – Danpe

0

Stai modificando la raccolta utilizzando qualsiasi altro codice? Solitamente ciò accade quando si enumera una raccolta in un ciclo e si tenta di modificare la raccolta.

+0

Non modificare nulla ... ho solo pochi UserControls con pochi thread, forse è qualcosa con i thread? – Danpe

Problemi correlati