[英]Exception when closing Form (thread + invoke)
我剛剛開始學習c#中的線程和方法,但我遇到了一個我無法找到解決方案的問題。
我制作了一個基本的C#表單程序,通過啟動一個線程並調用委托來不斷更新和顯示一個數字。
在Form1_load上啟動新線程:
private void Form1_Load(object sender, EventArgs e)
{
t = new System.Threading.Thread(DoThisAllTheTime);
t.Start();
}
Public void DoThisAllTheTime(不斷更新數字):
public void DoThisAllTheTime()
{
while(true)
{
if (!this.IsDisposed)
{
number += 1;
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
this.Invoke(yolo);
}
}
}
現在當我單擊表單的X按鈕時,我得到以下異常:
'System.Windows.Forms.dll中發生了'System.ObjectDisposedException'類型的未處理異常
無法更新已刪除的對象'
雖然我確實檢查了表格是否被處理掉了。
編輯:我添加了catch(ObjectDisposedException ex)到修復問題的代碼。 工作代碼:
public void DoThisAllTheTime()
{
while(true)
{
number += 1;
try {
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
this.Invoke(yolo);
}
catch (ObjectDisposedException ex)
{
t.Abort();
}
}
}
你this.IsDisposed
呼吁this.IsDisposed
總是過時的。 您需要攔截表單結束事件並明確停止該線程。 那么你根本不必進行IsDisposed
測試。
有很多方法可以做到這一點。 就個人而言,我會使用System.Threading.Tasks
命名空間,但是如果你想繼續使用System.Threading
,你應該定義一個成員變量_updateThread
,並在你的load事件中啟動它:
_updateThread = new System.Threading.Thread(DoThisAllTheTime);
_updateThread.Start();
然后在你的結束活動中:
private void Form1_Closing(object sender, CancelEventArgs e)
{
_stopCounting = true;
_updateThread.Join();
}
最后,使用檢查新的_stopCounting
成員變量的值來替換IsDisposed
測試:
public void DoThisAllTheTime()
{
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
while(!_stopCounting)
{
number += 1;
this.Invoke(yolo);
}
}
只需將此覆蓋放在表單類中:
protected override void OnClosing(CancelEventArgs e) {
t.Abort();
base.OnClosing(e);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Thread.CurrentThread.Abort();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.