Dinu Kuruppu
Dinu Kuruppu

Reputation: 165

Thread was being aborted C#

I have a form load splash screen, which contains a small gif image. Recently it start trowing an exception saying " Thread was being aborted" when it tries to load the main form. This is the Exception

System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectI(HandleRef graphics, HandleRef image, Int32 x, Int32 y, Int32 width, Int32 height)
   at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
   at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
   at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
   at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

This is what i've got on the splash form

public partial class Loading_Screen : Form
    {

        public Action worker { get; set; }

        public Loading_Screen(Action worker)
        {
            InitializeComponent();
            if (worker == null)
                throw new ArgumentOutOfRangeException();
            worker = worker;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Task.Factory.StartNew(worker).ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());
        }
    }

Main form

   public Dashboard_Form()
        {
            Thread t = new Thread(new ThreadStart(startform));
            t.Start();
            Thread.Sleep(5000);
            InitializeComponent();
            t.Abort();
        }

Any help would be appreciated

Upvotes: 2

Views: 10775

Answers (1)

Michael Puckett II
Michael Puckett II

Reputation: 6749

Use async await if possible:

public partial class Loading_Screen : Form
{
    public Loading_Screen()
    {
        InitializeComponent();
    }

    public Action Worker { get; set; }

    public Loading_Screen(Action worker)
    {
        InitializeComponent();
        Worker = worker ?? throw new ArgumentOutOfRangeException();
    }

    protected override async void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        await Task.Factory.StartNew(Worker);
        Close();
    }
}

You usually don't need a unique thread, and since you're attempting to abort it then it's a tell sign you don't. So borrow from the thread pool in main.

public void Dashboard_Form()
{
    ThreadPool.QueueUserWorkItem((o) => startform());
    Thread.Sleep(5000);
    InitializeComponent();            
}

With this you have to implement other means to cancel the thread. I'm posting an better solution using Task if you're open to it.

private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
public async void Dashboard_Form()
{
    if (cancellationTokenSource.IsCancellationRequested)
    {
        cancellationTokenSource.Dispose();
        cancellationTokenSource = new CancellationTokenSource();
    }

    var task = Task.Run(() => startform(), cancellationTokenSource.Token);
    await Task.Delay(5000);
    InitializeComponent();
    cancellationTokenSource.Cancel();
}

This still isn't the way I would implement it personally but I believe it might get you moving in the right direction. Just look for the cancellationToken in the startForm method and end the thread internally if it shows canceled.

Upvotes: 3

Related Questions