gpt4 book ai didi

c# - 显示表单时出现 ThreadState 异常

转载 作者:行者123 更新时间:2023-11-30 17:19:22 25 4
gpt4 key购买 nike

我有一个需要几秒钟加载的表单。因此,我想显示一个带有文本“正在加载,请稍候”的小表格。表单加载完成后,必须关闭加载表单。

所以,我做了一个简单的类,它在线程中显示加载表单:

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

在我的主要形式中:

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

但是。在这段代码之后,我在主窗体上做了一些事情:this.Opacity = 0;。此时,我可以在调试器中看到线程停止工作并抛出 ThreadStateException 并且加载表单消失。

这是为什么?

最佳答案

你的程序崩溃是因为你中止了线程但没有处理窗口。由于 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);
}
}

关于c# - 显示表单时出现 ThreadState 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4944850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com