我目前正在使用兩種形式和一個托盤圖標進行項目。但是,在顯示第二個窗體Form2時,我遇到了麻煩,它在以特定方式顯示後大約30秒鐘凍結。C# - 大約30秒後凍結窗體 - 多線程
第一種形式(Form1)始終顯示在背景中,只有兩個薄紅色按鈕覆蓋用戶顯示器兩側約7個像素,並且兩者之間的空間是透明的。這些按鈕用於在警報關閉時閃爍,並且它們可以成功使用下面的代碼。
運行此任務後,將創建一個新的Form2。 Form2顯示關於正在發生的警報的信息並允許確認,這也可以阻止紅色條閃爍。 Form1是在Form1的不透明度任務運行之後創建的。下面的代碼是在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]);
}));
}
創建兩種形式後,我有一個類,更新程序,即在一個BackgroundWorker(bgUpdater),用於獲取該警報的列表運行每隔10秒從Web API上下載一次,然後使該成員在其類中公開。 Form2有一個BackgroundWorker本身,然後在另一個10秒的時間間隔內從更新器中拉取該成員,並使用它創建可點擊的標籤並顯示其形式中每個當前報警的信息。
更新程序具有一項功能,用於在檢測到警報時發送Toast通知,並具有一個按鈕以將Form2打開到可以發送確認的正確頁面。該Toast通知按鈕的單擊事件運行下面的方法來打開窗體到正確的頁面:
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()
}
}
如果只是正常打開表單顯示窗體2(Form2.Activate()),也沒有問題,形式不凍結,但是當使用ShowManagementUI(結果監視器)顯示窗體時,Form2會在10-30秒之間的任何地方凍結,但Form1會一直閃爍紅色條。它不會拋出任何異常,但我有一種感覺,它可能試圖在UI線程上調用操作,但由於某種原因它被鎖定。
我不能爲我的生活找到爲什麼它會這樣做。有沒有人有任何建議追蹤這樣的凍結?
不使用的invoke(),因爲它可能會導致應用程序死鎖。使用BeginInvoke代替 – MickyD
感謝您的建議!那麼最好使用BeginInvoke呢? 我用BeginInvoke()替換了Invoke()的所有實例,但問題仍然存在 –