2010-08-27 18 views
5

Aquí está el mensaje de error que estoy recibiendo cuando intento abrir una OpenFileDialog en mi programa:STAThread falta, pero está ahí

"hilo actual se debe establecer en un solo departamento hilo (STA) antes de OLE se pueden realizar llamadas. Asegúrese de que su función principal tenga marcado STAThreadAttribute . Esta excepción es solo si se adjunta un depurador al proceso ".

El problema con este mensaje de error es que mi método Principal TIENE el atributo STAThread adjunto. No sé cómo manejar esto. ¿Cómo puedo agregar algo si ya está allí? Duplicarlo no es una buena opción, e intenté borrarlo, compilar la aplicación, agregarla y compilarla de nuevo sin éxito. Simplemente no entiendo.

private void btnOldFind_Click(object sender, EventArgs e) 
{ 
    openFileDialog1.Multiselect = false; 
    openFileDialog1.FileName = ""; 
    openFileDialog1.ShowHelp = false; 
    openFileDialog1.AutoUpgradeEnabled = true; 
    openFileDialog1.InitialDirectory = @"C:\"; 
    openFileDialog1.Filter = "Microsoft Installer (*.msi)|*.msi|All Files (*.*)|*.* "; 
    openFileDialog1.FilterIndex = 1; 
    openFileDialog1.RestoreDirectory = true; 

    if (openFileDialog1.ShowDialog() == DialogResult.OK) 
    { 
     textBoxOldInstallation.Text = openFileDialog1.FileName; 
    } 
} 

y el método principal es:

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 

Y no roscado se realiza de forma explícita. Solo un programa bastante básico para ser honesto.

modo Edit2 ::

Aquí está el mensaje de error completo que incluye pila de llamadas

System.Threading.ThreadStateException fue controlada mensaje = "hilo actual se debe establecer en apartamento solo hilo (STA) antes de que se puedan realizar llamadas OLE. Asegúrese de que su función Principal tenga marcado STAThreadAttribute.Esta excepción solo se produce si se adjunta un depurador al proceso. " Fuente = "" System.Windows.Forms StackTrace: en System.Windows.Forms.FileDialog.RunDialog (IntPtr hWndOwner) en System.Windows.Forms.CommonDialog.ShowDialog (propietario IWin32Window) en System.Windows.Forms .CommonDialog.ShowDialog() en MSI_Comparison_GUI.Form1.btnOldFind_Click (Object Sender, EventArgs e) en c: \ tfs \ DocuWare .NET \ DocuWare NewGen \ src \ Tools \ MSI_Comparison \ MSI_Comparison_GUI \ Form1.cs: línea 70 en System .Windows.Forms.Control.OnClick (EventArgs e) en System.Windows.Forms.Button.OnClick (EventArgs e) en System.Windows.Forms.Button.OnMouseUp (MouseEventArgs mevent) en System.Windows.Forms. Control.WmMouseUp (Mensaje & m, MouseButto botón ns, Int32 hace clic) en System.Windows.Forms.Control.WndProc (Mensaje & m) en System.Windows.Forms.ButtonBase.WndProc (Mensaje & m) en System.Windows.Forms.Button.WndProc (Mensaje & m) en System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Mensaje & m) en System.Windows.Forms.Control.ControlNativeWindow.WndProc (Mensaje & m) en System.Windows.Forms.NativeWindow. DebuggableCallback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW (MSG & msg) en System.Windows.Forms.Ap plication.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (Int32 dwComponentID, Int32 reason, Int32 pvLoopData) en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (razón Int32, contexto ApplicationContext) en System.Windows.Forms.Application.ThreadContext.RunMessageLoop (razón Int32, contexto ApplicationContext) en System.Windows.Forms.Application.Run (Form mainForm) en MSI_Comparison_GUI.Program.Main() en c: \ tfs \ DocuWare .NET \ DocuWare NewGen \ src \ Tools \ MSI_Comparison \ MSI_Comparison_GUI \ Program.cs: línea 18 en System.AppDomain._nExecuteAssembly (Assembly assembly, String [] args) en System.AppDomain .ExecuteAssembly (String assemblyFile, Evidencia assemblySecurity, String [] args) en Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() en System.Threading.ThreadHelper.ThreadStart_Context (estado Object) en System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback de devolución de llamada, el estado del objeto) en System.Threading.ThreadHelper.ThreadStart() InnerException:

+0

¿Puede mostrarnos el código, cómo se crea el diálogo? ¿Y creaste otro hilo en tu programa? –

+0

se ha agregado para su placer de lectura: P – Adkins

+0

¿Está seguro de que se está ejecutando en el hilo principal en ese punto y que OpenFileDialog1 se ha creado en el hilo principal? –

Respuesta

14

Podría ser que usted está enfrentando el siguiente problema reportado en Conectar :

.vshost.exe forces wrong threading model used when debugging a .exe if a .dll of the same name exists in same bin directory

De acuerdo con esa cuestión sucede que el proceso de alojamiento de Visual Studio, es decir, myprogram.vshost.exe impone un estado de apartamento incorrecto cuando tiene un myprogram.exe y un myprogram.dll archivo en su carpeta de salida.

El problema puede ser específico a alguna versión anterior de Visual Studio (2005), y no he sido capaz de reproducirlo utilizando VS 2010.

La solución obvia sería la de cambiar el nombre del archivo DLL o para mover el dll a otra carpeta.

La situación puede haber surgido porque ha cambiado el tipo de salida de su proyecto de la biblioteca de clases a la aplicación de Windows.

No está claro si Microsoft ha confirmado este problema o no, simplemente dice que el problema queda fuera de la responsabilidad del equipo de producto de VS.

+0

@Adkins: Solo tengo curiosidad: ¿Este ha sido realmente el problema? ¿Estás en VS 2005 entonces? –

+0

Dangit, estaba buscando algo así. Mi fu falló. – Will

+0

@ Hans Passant: Como no puedo reproducir el problema, es difícil saber la causa, personalmente sospecho que hay un error en el mecanismo vshost, pero tal vez esté relacionado con el equipo shell en MS. O a algún ingeniero de soporte perezoso ;-) –

3

No se puede decir sin código. Si una aplicación de consola, añada lo siguiente antes de llamar al método:

Console.Write(System.Threading.Thread.CurrentThread.ApartmentState); 

lo contrario,

MessageBox.Show(System.Threading.Thread.CurrentThread.ApartmentState); 

y ver lo que el estado de apartamento roscado realmente es.

+0

Es una aplicación básica de formularios de Windows sin hilos hechos a propósito. Usé ese mensaje como se sugirió y me dijo que el estado era MTA. Realmente no entiendo cómo puede ser eso porque, como dije, Main está marcado con [STAThread] como lo hace Visual Studio automáticamente, y no hago ningún otro subproceso que una llamada básica a OpenFileDialog. – Adkins

+0

@adkins ¿está seguro de que no está utilizando una clase de marco que enmascara el multihilo? ¿Te gusta BackgroundWorker o usar "BeginInvoke" en un delegado? El subprocesamiento múltiple no solo ** ocurre ** por accidente. ¿Puedes depurar y dejar que se vuelva a lanzar esa excepción? Si actualiza su pregunta con la pila de llamadas del objeto de excepción, probablemente pueda decirle dónde está ocurriendo la transición a MTA, si está utilizando una de estas clases marco que hacen la transición. – Will

+0

se agrega, pero no es bonita. No uso nada en el momento en que aparece este error. Simplemente estoy cargando el programa y haciendo clic en un botón para abrir OpenFileDialog. – Adkins

0

Intente establecer los puntos de interrupción en el procedimiento principal, el punto donde se crea el cuadro de diálogo y dónde se usa. Luego, observe en qué hilo (s) se encuentra realmente. Además, verifique cuál es el valor de Thread.CurrentThread.GetApartmentState() en esos puntos.

+0

como se indica arriba, el estado del apartamento actual es MTA, pero no estoy seguro de por qué. – Adkins

+0

@Adkins: ¿Es MTA en todas esas ubicaciones, incluso directamente en el método principal? –

+0

@ 0xA3 Coloqué el cheque como la primera instrucción en el método principal y fue MTA. Es en serio el atributo STAThread, la firma principal, luego el cheque. – Adkins

6

Tiene un rastro de pila imposible. Está claro que el enhebrado no es la causa del problema, todo se ejecuta en el hilo principal y el atributo [STAThread] en su método Principal establece el estado del apartamento. El rastro de la pila muestra que de hecho es el punto de entrada.

Bueno, malas noticias, algún tipo de complemento es farking con su hilo principal. Hacer algo desagradable como llamar a CoUninitialize demasiadas veces. Me ha sucedido esto una vez, me llevó un mes encontrarlo. Comience a diagnosticar esto con Project + Properties, pestaña Debug, marque "Habilitar la depuración del código no administrado". Eso le permite ver qué DLL se cargan en su programa, se muestra en la ventana de resultados.

La primera ventaja es cuando el diálogo muestra okay el tiempo primera pero falla el segundo tiempo. Luego tienes algún tipo de controlador de extensión de shell que ingresó a tu programa. Use la utilidad AutoRuns de SysInternals y desactive cualquier controlador de extensión de shell que no haya sido creado por Microsoft.

Se hace más difícil cuando el diálogo falla de inmediato. Luego use Debug + Windows + Modules y vaya a la lista de DLL. Preste atención a su origen, que se muestra en la columna Ruta. Desconfíe de cualquier cosa que no graznée como .NET o Microsoft DLL. Especialmente no tener un archivo de símbolos cuando habilitó el servidor de símbolos de Microsoft es una ventaja. Una buena forma de avanzar con esto es comparar esa lista con una que veas en otra máquina que no tenga este problema.

Tengo una historia de guerra sobre esto. Mi código COM estaba cayendo en cientos de máquinas, todo lo que tenía que pasar era un minivolcado. Me llevó un mes descubrir la fuente, un proyecto de código abierto llamado ffdshow. Muy distribuido, usando diferentes nombres también. Tenía un error, llamando a CoUnitialize dos veces más. El error estuvo presente en los lanzamientos durante dos años, pero se corrigió hace un año y medio. Muy difícil de diagnosticar, no me acerqué hasta que comencé a buscar versiones anteriores. Si ve ffdshow en su ventana de Módulos, entonces está cerca :)

Buena suerte, háganos saber al malhechor.

+0

"Tienes un rastro de pila imposible". ¿Cómo quieres decir "imposible"? La traza de pila se parece a una traza de depuración regular para mí ... –

+0

@ 0xA3: imposible como en "eso no debería quejarse nunca del estado del departamento". –

Cuestiones relacionadas