C# 线程正在被中止#

C# 线程正在被中止#,c#,multithreading,C#,Multithreading,我有一个表单加载启动屏幕,其中包含一个小的gif图像。最近,当它尝试加载主窗体时,它开始抛出一个异常,说“线程正在中止”。 这是个例外 System.Threading.ThreadAbortException: Thread was being aborted. at System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectI(HandleRef graphics, HandleRef image, Int32 x, Int32 y,

我有一个表单加载启动屏幕,其中包含一个小的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)
这是我在splash表上看到的

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

如有可能,请使用
async wait
,如有任何帮助,我们将不胜感激:

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();            
}
有了这个,您必须实现其他方法来取消线程。如果您愿意的话,我将使用
任务发布一个更好的解决方案

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,如果显示Cancelled,则在内部结束线程。

如果可能,请使用
async Wait

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();            
}
有了这个,您必须实现其他方法来取消线程。如果您愿意的话,我将使用
任务发布一个更好的解决方案

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,如果它显示Cancelled,则在内部结束线程。

您自己使用
t.abort()
中止线程,因此引发此异常也就不足为奇了。正如@Evk所说,我看到的问题太多,不需要线程。另外:如果(worker==null)抛出新的ArgumentOutOfRangeException();。。。在其设置之前,该方将采取采取采取行动之前的方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方是魔鬼的工作。如果你重视你的理智,就要避免它。。。这里的worker指的是参数。虽然正确使用“this”和命名在这里会有所帮助:)另外,您使用的是.NET的哪个版本?这也可以被清理和简化很多。愿意提供帮助。您自己使用
t.abort()
中止线程,所以引发此异常也就不足为奇了。我看到了很多问题,正如@Evk所说,不需要关于的线程。另外:如果(worker==null)抛出新的ArgumentOutOfRangeException();。。。在其设置之前,该方将采取采取采取行动之前的方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方方是魔鬼的工作。如果你重视你的理智,就要避免它。。。这里的worker指的是参数。虽然正确使用“this”和命名在这里会有所帮助:)另外,您使用的是.NET的哪个版本?这也可以被清理和简化很多。愿意帮忙。