ThreadState exception throws when showing form

I have a form that takes a few seconds to load. So I want to show a small form with the text "Download, please wait." When the form is completed, the boot form should be closed.

So, I made a simple class that shows the boot form in the stream:

public class ShowLoadingForm
{
    Thread _thread;

    public void Show()
    {
        try
        {
            _thread = new Thread(new ThreadStart(ShowForm));
            _thread.SetApartmentState(ApartmentState.STA);
            _thread.IsBackground = true;
            _thread.Start();
        }
        catch (Exception ex)
        {
            ErrorMessages.UnknownError(true, ex);
        }
    }

    private void ShowForm()
    {
        LoadingForm f = new LoadingForm();
        f.TopMost = true;
        f.ShowInTaskbar = true;
        f.SetText(" Loading... ");
        f.Show();
    }

    public void Close()
    {
        _thread.Abort();
    }
}

In the main form, I have:

_loadingForm = new ShowLoadingForm();
_loadingForm.Show();

BUT. After this piece of code, I do something in the main form: this.Opacity = 0 ;. At this point, I see in the debugger that the thread is stopped and ThreadStateExceptionthrown, and the download form disappears.

Why is this?

+3
source share
6 answers

, , . - Windows, ThreadStateException, . , .

, , .

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

class Loader : IDisposable {
    private AutoResetEvent initialized = new AutoResetEvent(false);
    private Form loadForm;
    private Rectangle ownerRect;
    private bool closeOkay;

    public Loader(Form owner, Form pleaseWait) {
        if (pleaseWait.IsDisposed) throw new InvalidOperationException("Create a *new* form instance");
        loadForm = pleaseWait;
        loadForm.TopMost = true;
        loadForm.ShowInTaskbar = false;
        loadForm.StartPosition = FormStartPosition.Manual;
        ownerRect = new Rectangle(owner.Location, owner.Size);
        loadForm.Load += delegate {
            loadForm.Location = new Point(
                ownerRect.Left + (ownerRect.Width - loadForm.Width) / 2,
                ownerRect.Top + (ownerRect.Height - loadForm.Height) / 2);
            initialized.Set();
        };
        loadForm.FormClosing += new FormClosingEventHandler((s, ea) => {
            ea.Cancel = !closeOkay;
        });
        var t = new Thread(() => {
            Application.Run(loadForm);
        });
        t.SetApartmentState(ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
        initialized.WaitOne();
    }

    public void Dispose() {
        if (loadForm == null) throw new InvalidOperationException();
        loadForm.Invoke((MethodInvoker)delegate {
            closeOkay = true;
            loadForm.Close(); 
        });
        loadForm = null;
    }

}

:

    private void button1_Click(object sender, EventArgs e) {
        using (new Loader(this, new LoadingForm())) {
            System.Threading.Thread.Sleep(3000);
        }
    }
+1

(). , ( - , )).

public partial class MainForm : Form
{
    public MainForm()
    {
        SplashForm sf = new SplashForm();
        sf.Show();

        InitializeComponent();

        this.SuspendLayout();
        // Do the positioning...
        this.ResumeLayout();

        sf.Close();
    }
}
+1

, , , , .

0

, load, , .

this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
0

, , , , , , , - .

    static void ThreadFunc()
    {
        _splash = new Splash();
        _splash.Show();
        while (!_shouldClose)
        {
            Application.DoEvents();
            Thread.Sleep(100);
            if (new Random().Next(1000) < 10)
            {
                _splash.Invoke(new MethodInvoker(_splash.RandomizeText));
            }
        }
        for (int n = 0; n < 18; n++)
        {
            Application.DoEvents();
            Thread.Sleep(60);
        }
        if (_splash != null)
        {
            _splash.Close();
            _splash = null;
        }
    }

Splash - . :

    static public void ShowSplash()
    {
        _shouldClose = false;
        Thread t = new Thread(ThreadFunc);
        t.Priority = ThreadPriority.Lowest;
        t.Start();
    }

. Main() . , , :

    internal static void RemoveSplash()
    {
        _shouldClose = true;
    }
0

Source: https://habr.com/ru/post/1790939/


All Articles