我有一个表单加载启动画面,其中包含一个小的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();
}
任何帮助将不胜感激
答案 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,如果它显示已取消,则在内部结束该线程。