PkLab.Net - Meccatronica
Italiano English

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

Last update: 21/09/2009 - Viewed: 2117 dal 21 Sep 2009 - Vote:0.0 (0 Votes)
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 <objbase.h>  //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.

Keywords: C/CPP, Visual Studio
Categories: Visual Studio
Vote this page
0    1    2    3    4    5   

Leave your comment:

Name:

Email:

Emails will not be visible or used in any way, and are not required

Comment:


Verify code:


Type the code you can see here on the left
 

Note:
  • Please keep comments relevant
  • Any content deemed inappropriate or offensive may be edited and/or deleted
  • No HTML code is allowed. Line breaks will be converted automatically. URLs will be auto-linked. Please use BBCode to format your No HTML code is allowed. Please use BBCode to format your text
  • URLs, complete of "http://" o "mailto:" , will be auto-linked
  • Nota: questo materiale è di proprietà di Pk Lab ed è utilizzabile liberamente a condizione di citarne la fonte
    [Home Page]  [Search]
    Copyright PkLab (c) 2009
    Contatto: