我的程序加载时,我在背景线程上显示一个飞溅屏幕。一旦加载,我将中止该线程,因为它的唯一目的是显示现已加载的飞溅形式。

我的问题是,当中止线程时,它会抛出 ThreadAbortException 用户只需单击“继续”。

我该如何处理?我试图像这样抑制它 - >

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

        }

但是我有一种感觉会让我在这里大喊大叫,而且它行不通。

谢谢!

有帮助吗?

解决方案

您无需取消线程。我将用代码举例说明。

在飞溅屏幕表格中:

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

在program.cs文件中:

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

现在,当您的主要方法启动时,在线程中显示飞溅:

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

t.Start();

...当您希望它关闭时,只需关闭它:

Program.CloseSplash();

那么,您不必担心流产线程;它将优雅地退出。

其他提示

请参阅以下链接进行Google搜索(首先返回):

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

特别注意此部分:

当在线程上调用此方法时,系统将抛出 threadabortexception 在线程中流产。 threadabortexception 是可以通过应用程序代码捕获的特殊例外 重置 叫做。 重置 取消中止请求,并防止 threadabortexception 从终止线程。未执行的最终块在线程中止之前被执行。

不建议使用ThreadAbort。这是邪恶的。为什么不使用(自动/手动)RESETEVENT等其他机制?使用飞溅屏幕启动线程,等待活动。如果其他代码已完成加载内容,请设置事件EN允许飞溅屏幕以正常(不错的)方式关闭自身。

一些要点。线程非例外是线程中止的原因。这不是您打电话堕胎的副作用。当您在线程上调用流产时,运行时会迫使线程型异常传播到线程。可以捕获此例外,因为它允许用户在线程中止之前进行一些清理。

然后将自动重新自动重新启动,以确保螺纹流产。如果抓住了例外,如果没有再生,则线程将永远不会流产。

实际上,真正聪明的设计。

因此,捕获该异常确实可以。实际上你应该。但是只捕获该特定例外,而不是一般例外。 (如下所示)

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

将异常类型更改为 threadabortexception 并添加一个电话 resetabort()

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

通常,流产线程被认为是非常不好的练习,并且可能导致各种难以追踪错误。您是否考虑过弄清楚一种方法 关闭飞溅窗口 或使用某种 轮询 设置标志时停止线程?

为什么要这么做?只需设置线程进行轮询的标志,然后最终将线程拾取时,它将自身关闭。

尝试此代码。对我来说很好。

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

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

我已经使用了FredrikMörk建议的解决方案。这是非常清晰和优雅的。否则,如果我们在启动真实应用程序(application.run(mainform ...))之前实例化飞溅表格,我会发现问题。

它提出了由台阶引起的无效验证,在呼叫线程中仍然不存在。要直接在线程t中创建句柄(并跳过此例外!)尝试以这种方式启动飞溅表:

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

t.Start();

而且,如果您打算在程序的更多分支中调用Closesplash方法,请在第一个调用后强制零值:

    private static Splash _splash = null;
    public static void CloseSplash()
    {
        if (_splash!= null)
        {
            _splash.CloseSplash();
            _splash=null;
        }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top