Italiano - English

Eccezione non gestita di tipo 'System.Threading.ThreadStateException' in System.

Translation for this document is not available or is not complete,
if you are intrested to receive information please write to

Un workaround per utilizzare oggetti COM in esecuzione dal debug di Visual Studio 8 (2005). 

Descrizione

Con Microsoft Visual C++ 8(2005), quando una una applicazione /CLR viene eseguita dal debugger e si utilizza un oggetto COM come ad esempio una finestra di dialogo, a runtime viene lanciata la seguente eccezione.

Eccezione non gestita di tipo 'System.Threading.ThreadStateException' in System.Windows.Forms.dll

Informazioni aggiuntive: Prima di effettuare chiamate OLE, occorre impostare il thread corrente sulla modalità Single Thread Apartment (STA). Assicurarsi che la funzione Main sia contrassegnata con STAThreadAttribute. Eccezione generata solo se un debugger è associato al processo.

ciò accade anche se la modalità STA è correttamente impostata nel modo seguente:

[STAThreadAttribute]
int main(array ^args)
{

  //this return MTA if debugger is active
  Threading::ApartmentState AState = Threading::Thread::CurrentThread->GetApartmentState();

 Corpo della funzione main

}

Soluzione

Pare che il Framework .NET 2.0 ignori STAThreadAttribute impostando comunque la modalità MTA, ma solo se l'applicazione viene lanciata dal debugger. 

Per forzare la creazione del thread principale sulla modalita STA è necessario inizializzare manualmente l'ambiente COM sul thread, nel seguente modo:

#include   //richiesto per CoUninitialize e CoInitialize  

[STAThreadAttribute] int main(array ^args)
{
  // Attivare gli effetti visivi di Windows XP prima di creare i controlli
  Application::EnableVisualStyles();   
  Application::SetCompatibleTextRenderingDefault(false);    //this return MTA if debugger is active  
  Threading::ApartmentState AState = Threading::Thread::CurrentThread->GetApartmentState();    
  
  // Creare la finestra principale ed eseguirla
  /*
  per qualche bug o motivo sconosciuto, in fase di esecuzione da debug,
  il tread principale viene impostato come MTA (MultiThreadApparment) anche se
  configurato con [STAThreadAttribute].
  Cio' impedisce di lanciare oggetti COM (esempio finestre di dialogo) in  fase di debug.
  La soluzione seguente è un workaround a questo problema
  */
  if(AState !=(Threading::ApartmentState::STA))
  {
    CoUninitialize(); 
    CoInitialize(NULL);
  }   
  //now this return STA if debugger is active   
  Threading::ApartmentState AState = Threading::Thread::CurrentThread->GetApartmentState();    
  Application::Run(gcnew Form1());    
  
  CoUninitialize();   //probabilmente non è necessario
  return 0; 
  }

Non è molto chiaro il motivo per cui questo è necessario, quindi perchè funziona, tuttavia, dopo aver perso moltissimo tempo a risolvere il problema, si accetta di utilizzare questo workaround. Se qualche lettore vuole aggiungere maggiori dettagli, può farlo nei commenti in fondo alla pagina.

Vote this page:

1 Comments:

#1 Sent by goldfishka 06-05-2011

Thank you, very nice post.

Leave your comment:

Note:
  • Your email email will not be visible or used in any way, and is not required
  • Please keep comments relevant
  • Any content deemed inappropriate or offensive may be edited and/or deleted
  • HTML code is not allowed. Please use BBCode to format your text
    [b]bold[/b], [u]underline[/u], [i]italic[/i], [code]code[/code]
The coding examples presented here are for illustration purposes only. The author takes no responsibility for end-user use
This work is property of Pk Lab. You can use it for free but you must retain author's copyright.