线程被中止C#

时间:2018-05-21 12:30:07

标签: c# multithreading

我有一个表单加载启动画面,其中包含一个小的gif图像。最近,当它试图加载主窗体时,它开始抛出一个异常,说“线程被中止”。 这是例外

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)

这就是我在启动表格上的内容

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());
        }
    }

主要表格

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

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

如果可能,请使用async await

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();
    }
}

你通常不需要一个独特的线程,并且因为你试图中止它然后它就是你没有的告诉标志。所以从main中的线程池中借用。

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

有了这个,你必须实现取消线程的其他方法。如果您愿意,我会使用Task发布更好的解决方案。

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();
}

这仍然不是我个人实施的方式,但我相信它可能会让你朝着正确的方向前进。只需在startForm方法中查找cancellationToken,如果它显示已取消,则在内部结束该线程。