[英]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.