[英]C# - Form freezing after about 30 seconds - Multithreading
我目前正在一个具有两个表单和一个托盘图标的项目中。 但是,当显示第二个窗体Form2时,我遇到了麻烦,即它只是以某种方式显示大约30秒后就冻结了。
第一种形式(Form1)始终显示在背景中,只有两个细的红色按钮在用户监视器的每一侧覆盖大约7个像素,并且它们之间的空间是透明的。 当警报响起时,这些按钮将闪烁,并使用下面的代码成功闪烁。
运行此任务后,将创建一个新的Form2。 Form2显示有关即将关闭的警报的信息,并允许进行确认,这也使红色条停止闪烁。 在运行Form1的不透明度任务后立即创建Form2。 下面的代码是Program.cs的主要功能
redBarForms = new List<Form1>();
foreach (var screen in Screen.AllScreens)
{
var form = new Form1();
form.Opacity = 0d;
form.Show();
form.WindowState = FormWindowState.Normal;
form.Location = screen.WorkingArea.Location;
form.WindowState = FormWindowState.Maximized;
redBarForms.Add(form); // Only one is added right now, working from one screen
}
// Begin the loop which checks to see if the bars should be flashing.
Task.Run(() =>
{
while (true)
{
while (flashingAlertBars)
{
for (int i = 1; i <= 100; i++)
{
foreach (var form in redBarForms)
{
form.Invoke(new Action(() =>
{
form.Opacity = i / 100d;
}));
i += 9;
}
Thread.Sleep(50);
}
for (int i = 100; i >= 1; i--)
{
foreach (var form in redBarForms)
{
form.Invoke(new Action(() =>
{
form.Opacity = i / 100d;
}));
i -= 9;
}
Thread.Sleep(50);
}
}
}
});
MainForm = new Form2();
// Start the updater on a background worker so that it doesn't
affect the UI thread
BackgroundWorker bgUpdater = new BackgroundWorker();
bgUpdater.WorkerSupportsCancellation = true;
bgUpdater.DoWork += Updater_BGWorker_DoWork;
bgUpdater.RunWorkerAsync();
// Start Form1
if (!redBarForms[0].IsDisposed)
{
redBarForms[0].Invoke(new Action(() =>
{
Application.Run(redBarForms[0]);
}));
}
创建这两种形式后,我有一个在Updateer上运行的类,该类在BackgroundWorker(bgUpdater)上运行,该类每10秒从Web API发出警报的列表,然后将该成员公开类。 Form2本身具有BackgroundWorker,然后在另一个10秒间隔内将其从Updater中拉出,并使用它来创建可单击的标签并以其形式显示有关每个当前警报的信息。
Updater具有在检测到警报时发送烤面包通知的功能,并且具有将Form2打开到可以发送确认的正确页面的按钮。 吐司通知按钮的click事件运行以下方法以将表单打开到正确的页面:
static public void ShowManagementUI(Result monitor)
{
if (Application.OpenForms.OfType<Form2>().Count() > 0)
{
if (MainForm.InvokeRequired)
{
MainForm.Invoke(new Action(() =>
{
MainForm.ShowWithResult(monitor); //This just does an Activate()
}));
}
}
else
{
if (MainForm.IsDisposed)
MainForm = new Form2();
MainForm.Show();
MainForm.ShowWithResult(monitor); //This just does an Activate()
}
}
仅通过正常打开窗体(Form2.Activate())来显示Form2时,没有问题,窗体也不会冻结,但是当使用ShowManagementUI(Result Monitor)显示窗体时,Form2会在10到30秒之间的任何时间冻结,但是Form1一直闪烁其红色条。 它不会引发任何异常,但是我感觉到它可能正在尝试在UI线程上调用操作,但是由于某种原因或另一种原因它被锁定。
我一生无法找到为什么会这样做。 有人对跟踪这样的冻结有任何建议吗?
调用不透明度增加的for
循环中的Application.DoEvents
,以使UI线程有机会呈现更改。 50ms的间隔也很小。 尝试更大的数字。
但这通常不是动画的好主意:P
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.