Appartamento a thread singolo: impossibile creare un'istanza del controllo ActiveX
-
07-07-2019 - |
Domanda
Devo ottenere informazioni sugli stili CSS applicati nella pagina HTML. Ho usato AxWebBrowser e ho provato IHTMLDOMNode. Sono in grado di ottenere tutti i dati di cui ho bisogno e spostare il codice nella mia applicazione. Il problema è che questa parte è in esecuzione all'interno del lavoratore in background e ho ottenuto un'eccezione durante il tentativo di istanziare il controllo.
AxWebBrowser browser = new AxWebBrowser();
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated
because the current thread is not in a single-threaded apartment.
Esiste un modo per risolvere questa o un'altra opzione oltre a AxWebBrowser?
Soluzione
Il problema che si sta verificando è che la maggior parte delle API di thread / worker in background creerà il thread in uno stato Multithreaded Apartment. Il messaggio di errore indica che il controllo richiede che il thread sia un appartamento a thread singolo.
Puoi aggirare il problema creando tu stesso un thread e specificando lo stato dell'appartamento STA sul thread.
var t = new Thread(MyThreadStartMethod);
t.SetApartmentState(ApartmentState.STA);
t.Start();
Altri suggerimenti
Vai avanti e aggiungi [STAThread] alla voce principale della tua applicazione, questo indica che il modello di threading COM è un appartamento a thread singolo (STA)
esempio:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WebBrowser());
}
}
Se hai utilizzato [STAThread]
per la voce principale dell'applicazione e ricevi ancora l'errore, potresti dover effettuare una chiamata thread-safe al controllo. qualcosa come sotto. Nel mio caso con lo stesso problema ha funzionato la seguente soluzione!
Private void YourFunc(..)
{
if (this.InvokeRequired)
{
Invoke(new MethodInvoker(delegate()
{
// Call your method YourFunc(..);
}));
}
else
{
///
}