Il CLR non è stato in grado di passare dal contesto COM per 60 secondi

Sto ottenendo questo errore sul codice che prima funzionava. Non ho cambiato il codice.

Ecco l’errore completo:

Il CLR non è stato in grado di passare dal contesto COM 0x3322d98 al contesto COM 0x3322f08 per 60 secondi. Il thread che possiede il contesto / l’appartamento di destinazione è più probabile che effettui un’attesa senza pompaggio o che elabori un’operazione molto lunga senza pompare messaggi di Windows. Generalmente, questa situazione ha un impatto negativo sulle prestazioni e può persino portare a un’applicazione non retriggers o all’utilizzo della memoria che si accumula continuamente nel tempo. Per evitare questo problema, tutti i thread a thread singolo apartment (STA) devono utilizzare i primitivi di attesa di pompaggio (come CoWaitForMultipleHandles) e pompare regolarmente i messaggi durante le operazioni a esecuzione prolungata.

Ed ecco il codice che lo ha causato:

var openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); openFileDialog1.DefaultExt = "mdb"; openFileDialog1.Filter = "Management Database (manage.mdb)|manage.mdb"; //Stalls indefinitely on the following line, then gives the CLR error //one minute later. The dialog never opens. if(openFileDialog1.ShowDialog() == DialogResult.OK) { .... } 

Sì, sono sicuro che la finestra di dialogo non è aperta in background, e no, non ho alcun codice COM esplicito o marshalling non gestito o multithreading.

Non ho idea del perché OpenFileDialog non si aprirà – qualche idea?

Immaginato: ti porta automaticamente all’ultima posizione in cui ti sei guardato ogni volta che si apre la finestra di dialogo. Se quella posizione è un percorso di rete che non esiste più (ad esempio, l’altro computer è spento), si bloccherà per sempre.

La mia soluzione alternativa è la seguente:

 string initialDirectory = ...; //Figure out an initial directory from somewhere openFileDialog1.InitialDirectory = !Directory.Exists(initialDirectory) ? Path.GetPathRoot(Environment.SystemDirectory) : initialDirectory; 

Quindi, si lamenta di un contesto COM anche se non si utilizza esplicitamente la COM perché si apre una finestra di dialogo shell nativa sotto tutto quel bel codice c #, e la shell usa COM.

Ciò che questo messaggio ti sta dicendo è che qualunque cosa stia cercando di fare, lo sta facendo sul thread dell’interfaccia utente e non in un modo carino, e sembra che ci voglia molto tempo. Ovviamente tutto ciò che è sbagliato non è colpa tua, quindi puoi ignorare la maggior parte dei consigli che ti danno.

Cose da provare:

  1. Innanzitutto proverei, come suggerisce AaronLS , semplificando il più ansible il tuo openFileDialog . Prova a non impostare nulla; basta creare un nuovo ragazzo e chiamare ShowDialog() . Se questo risolve il problema, hai appena dato parametri malformati e possiamo parlare delle implicazioni di ciò. Tuttavia, se non funziona, significa che qualcosa sta andando storto nel guscio.

  2. Una ansible ragione per cui questo potrebbe accadere è che hai installato un’estensione della shell che sta facendo qualcosa di male. La cosa migliore da fare è l’ debug->break all break-in (ctrl+break in Visual Studio penso, o debug->break all sulla barra dei menu) e ottenere lo stack completo per noi. Dovremmo essere in grado di identificare il colpevole vedendo chi è in pila quando appare la finestra di dialogo.

Una soluzione al problema è accedere al menu Debug -> Eccezioni -> Gestisci debug degli assistenti in Visual Studio e deselezionare il ContextSwitchDeadlock

Da http://blog.wpfwonderland.com/2007/08/16/clr-has-been-unable-to-transition-from-com-context-for-60-seconds/

Aggiornamento: per favore, non downvotare, se si pensa abbastanza, che la soluzione alternativa è una pessima idea. Un certo numero di persone ha provato una serie di soluzioni elencate come risposte qui, ma la mia soluzione è stata l’unica cosa che li ha aiutati. Ecco perché la risposta ha ancora il punteggio positivo.

Ho avuto questo problema mentre lavoravo con un database di grandi dimensioni e ha reso il blocco dell’interfaccia utente per un lungo periodo. Così ho inserito i codici in un BackgroundWorker e ora il problema non c’è più. grazie a @i_am_jorf

Ciò che questo messaggio ti sta dicendo è che qualunque cosa stia cercando di fare, lo sta facendo sul thread dell’interfaccia utente e non in un modo carino, e sembra che ci voglia molto tempo.

 private void btnConvert_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; bgwConvert.RunWorkerAsync(); } private void bgwConvert_DoWork(object sender, DoWorkEventArgs e) { //My taking-lots-of-time codes } private void bgwConvert_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Cursor = Cursors.Default; MessageBox.Show("Done"); } 

Ho anche avuto questo problema e l’ho risolto cambiando il mio framework .Net in quello più recente (.Net framework 4.5 nel mio caso; dalle proprietà del progetto Window-> Debug-> .Net Framework ), e cambiando il tipo di CPU da x86 a qualsiasi CPU (nelle proprietà del progetto Finestra-> Build-> Target piattaforma ).

Qualche istante fa ho avuto gli stessi problemi, la soluzione nel mio caso era semplice: pulire la soluzione e ricostruirla!

Sto usando Visual Studio 2015.

Spero che questo aiuti.