Pregunta

Estoy mostrando una pantalla de bienvenida en un subproceso en segundo plano mientras mis cargas del programa. Una vez que se carga estoy abortar el hilo, ya que es único propósito era mostrar un formulario de inicio Ya Cargando.

Mi problema es que cuando abortar un hilo que arroja un ThreadAbortException que el usuario sólo puede hacer clic en Continuar en.

¿Cómo puedo lidiar con esto? Yo estaba tratando de suprimirlo como tal ->

            try
        {
            Program.splashThread.Abort();
        }
        catch(Exception ex)
        {

        }

pero tengo la sensación de que se va a conseguir que me grite aquí y no funciona de ninguna manera.

Gracias!

¿Fue útil?

Solución

No es necesario cancelar el hilo. Voy a ejemplificar con el código.

En la forma pantalla de presentación:

public void CloseSplash()
{
    Invoke((MethodInvoker)delegate
    {
        this.Close();
    });
}

En el archivo Program.cs:

private static Splash _splash = null;
public static void CloseSplash()
{
    if (_splash!= null)
    {
        _splash.CloseSplash();
    }
}

Ahora, cuando su método principal comienza, mostrar el chapoteo en un hilo:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
    _splash.ShowDialog();
}));

t.Start();

... y cuando quiere que se cierre, simplemente cerrarla:

Program.CloseSplash();

A continuación, usted no necesita preocuparse por abortar el hilo; sino que terminará con gracia.

Otros consejos

Por favor, consulte el siguiente enlace obtenido haciendo una búsqueda en Google (primer resultado devuelto):

http://msdn.microsoft.com/en-us/library /5b50fdsz.aspx

Prestar especial atención a esta parte:

Cuando se invoca este método en un hilo, el sistema lanza un ThreadAbortException en el hilo a abortar. ThreadAbortException es una excepción especial que puede ser capturado por el código de la aplicación, pero es re-lanzado al final del bloque catch a menos que ResetAbort se llama. ResetAbort cancela la solicitud para abortar, y evita que el ThreadAbortException de la terminación de la rosca. No ejecutados por último secuencias se ejecutan antes de que se abortó el hilo.

El uso de ThreadAbort no se recommened. Es el mal. ¿Por qué no usar otro mecanismo como un (/ Manual Auto) ResetEvent? Iniciar el hilo con la pantalla de bienvenida, esperar en el evento. Si el otro código se realiza la carga cosas, establecer el evento es permitir que la pantalla de bienvenida para cerrar en sí de la forma habitual (agradable).

Algunos puntos. La excepción es la razón ThreadAbort el hilo se aborta. No es un efecto secundario de que llamar a abortar. Cuando se llama a abortar en un hilo, el tiempo de ejecución obliga a una excepción ThreadAbort se propaguen a la rosca. Esta excepción puede ser capturado, ya que permite al usuario realizar alguna tarea de limpieza antes aborta el hilo.

La excepción se relanza automáticamente para garantizar que el hilo se aborta. Si la excepción fue capturado y si no se relanza el hilo nunca abortar.

Diseño realmente inteligente realidad.

Por lo que es muy bien para tomar esa excepción. De hecho, usted debe. Pero coger sólo eso excepción específica y no la excepción general. (Como se muestra a continuación)

catch(ThreadAbortException ex)
{
   //This is an expected exception. The thread is being aborted
}

Cambiar el tipo de excepción a ThreadAbortException y añadir una llamada a ResetAbort ()

    try
    {
        Program.splashThread.Abort();
    }
    catch(ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }

En general, abortando las discusiones se considera muy mala práctica y puede dar lugar a todo tipo de difícil localizar a los insectos. ¿Ha pensado en averiguar una manera de simplemente cierre la ventana de inicio o utilizar algún tipo de sondeo para detener el hilo cuando un indicador se ha establecido?

¿Por qué haces eso? Sólo hay que establecer una bandera que las encuestas de hilo, luego con el tiempo cuando el hilo se recoge que cerrarán en sí.

Trate de este código. Está trabajando muy bien para mí.

void splash()
{
    try {
        SplashScreen.SplashForm frm = new SplashScreen.SplashForm();
        frm.AppName = "HR";

        Application.Run(frm);
    }
    catch (ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }
}

He utilizado la solución sugerida por Fredrik Mörk. Es muy claro y elegante. De lo contrario, me encontré con un problema si una instancia del formulario de inicio antes de lanzar la aplicación real (application.run (MainForm ...)):

se plantea una invalidOprationException causada por la forma de manejar aún no existe en el llamado hilo. Para crear el mango directamente en el hilo t (y omitir esta excepción!) Tratan de poner en marcha el formulario de inicio de esta manera:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
     Application.Run(_splash);
}));

t.Start();

y, si va a llamar al método closeSplash en más ramas del programa, forzar el valor nulo después de la primera llamada:

    private static Splash _splash = null;
    public static void CloseSplash()
    {
        if (_splash!= null)
        {
            _splash.CloseSplash();
            _splash=null;
        }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top