【发布时间】:2021-10-26 09:51:35
【问题描述】:
我正在尝试制作一个异步计时器,它将关闭所有打开的表单(以线程安全的方式)(除了BaseWindow)并打开一个新的LoginScreen 表单。目前所有表单都已关闭,但当新的 LoginScreen 表单启动时,它的 UI 被冻结。
代码如下:
{
public static Form[] OpenForms
{
get
{
Form[] forms = null;
int count = Application.OpenForms.Count;
forms = new Form[count];
if (count > 0)
{
int index = 0;
foreach (Form form in Application.OpenForms)
{
forms[index++] = form;
}
}
return forms;
}
}
delegate void CloseMethod(Form form);
static private void CloseForm(Form form)
{
if (!form.IsDisposed)
{
if (form.InvokeRequired)
{
CloseMethod method = new CloseMethod(CloseForm);
form.Invoke(method, new object[] { form });
}
else
{
form.Close();
}
}
}
static public void CloseAllForms()
{
// get array because collection changes as we close forms
Form[] forms = OpenForms;
// close every open form
foreach (Form form in forms)
{
if (form.GetType() != typeof(BaseWindow))
{
CloseForm(form);
}
}
}
private void PollUpdates(object sender, EventArgs e)
{
;
if (Program.Globalsession.SessionId != default(Guid))
{
if (DateTime.Compare(Program.Globalsession.ValidTo, DateTime.Now) < 0)
{
CloseAllForms();
var login = new LoginScreen();
login.Show();
}
}
}
public BaseWindow()
{
InitializeComponent();
var login = new LoginScreen();
login.Show();
var theTimer = new System.Timers.Timer(5000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();
}
}
知道我做错了什么吗?
【问题讨论】:
-
我的猜测是您尝试在非 STA 线程上启动登录表单。
¯\_(ツ)_/¯意思是非 UI 线程 -
乍一看,
OpenForms和CloseMethod是静态的似乎很可疑。更明智的是拥有BaseForm : Form并在 BaseForm 中实现这些方法。最好是虚拟的或抽象的,这样您就可以在您创建的每个表单中覆盖它们。 -
@TheGeneral
System.Threading.Thread.CurrentThread.GetApartmentState();显示 STA -
那我没主意了
-
@Leron_says_get_back_Monica 即使我评论了这些功能的所有用法,用户界面仍然冻结