且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

线程中止异常随机发生

更新时间:2023-12-05 09:48:28

你正在倒退。您正在运行的代码位于UI(启动)线程上。所有UI STUFF,包括你的微调形式必须在UI线程上。每个UI表单和控件的每一点触摸都必须在UI线程上完成。创建一个显示表单或控件的线程是不行的。



这是你必须把它放在后台线程上的工作。

Hi,

I am working on excel plugin, when I need to show a spinner till some operation happens in the background. I took an approach where I have placed the spinner image(gif) in another windows form and call it in a separate thread. Once the operation gets complete, I abort this thread which is running the spinner form.

This is giving thread abort exception randomly.

What I have tried:

Here is my code:

Spinner form:

<pre>public partial class LoadingScreen : Form
    {
        private LoadingScreen _loadingScreen = null;
        private Thread oThread = null;

        public LoadingScreen()
        {
            InitializeComponent();
        }

        public LoadingScreen(bool showloading)
        {
            InitializeComponent();

            ShowLoadingScreen();
        }
        public void FocusLoading()
        {
            if (_loadingScreen == null)
                ShowLoadingScreen();
            if (oThread != null)
            {
                this.Activate();
            }
        }
        private void ShowFormOpacity()
        {
            _loadingScreen = new LoadingScreen();
            _loadingScreen.Opacity = .75;
            _loadingScreen.Controls["lblLoading"].Visible = false;
            if (_loadingScreen != null)
                Application.Run(_loadingScreen);
        }

        public void CloseFormInstance()
        {
            if (oThread != null)
            {
                try
                {
                    _loadingScreen = null;
                    oThread.Abort();
                    oThread.Join();
                }
                catch (Exception ex) { }
            }
        }
        public void ShowLoadingScreen()
        {
            if (_loadingScreen != null)
                return;
            oThread = new Thread(new ThreadStart(ShowFormOpacity));
            oThread.IsBackground = false;
            oThread.SetApartmentState(ApartmentState.STA);
            oThread.Start();
            while (_loadingScreen == null || _loadingScreen.IsHandleCreated == false)
            {
                System.Threading.Thread.Sleep(50);
            }
        }
    }




Calling the spinner form from ThisAddIn.cs

private LoadingScreen screen;



public void LoadingScreen(bool showloading)
{
    if (screen != null)
    {
        screen.FocusLoading();
    }
    else
    {
        screen = new LoadingScreen(showloading);
    }
}
public void CloseFormInstance()
{
    if (screen != null)
    {
        screen.CloseFormInstance();
    }
}




Why is the thread abort exception happens sometimes?

You're doing it backwards. The code you're running is on the UI (startup) thread. ALL UI STUFF, including your "spinner form" MUST be on the UI thread. Every little touch of every UI form and control MUST be done on the UI thread. Creating a thread to show a form or a control on it isn't going to work.

It's the WORK you have to put on a background thread.