當多執行緒用到主執行緒的 Control 時, 一般就會藉助 Invoke 切換回主執行緒, 不然就會出現跨執行緒操作 Control 的錯誤。
當你關閉 Form 後, 非主執行緒還在 Invoke 中, 程式就會發生死結一直被 hand 在 Control.Invoke 的地方,
不知道這部份有沒有人知道什麼指令可以強制關閉呢...?
上網 google 似乎沒什麼人在討論這一塊, 彷彿這種事不會發生似的, 卻讓我遇到了... >"<
如果有什麼好方法的話... 請告知小弟一聲, 感激不盡!!
如果你也遇到同我一樣的問題, 且還不知道如何解的話可以試著用以下方法處理:
分別產生一個 bool 變數 FlagInvoke 用來記錄是否正在 Invoke 中, 和一個 bool 變數 FlagClose 用來記錄是否要結束 Form.
關閉 Form 的時候不直接用多寫一個 CloseForm 函數來避開程式正在 Invoke 的問題。
片段程式碼如下, 紅色部份是為了解決 Invoke deadlock 而加的:
using T512KDLL; // 自己寫用來接收期交所 512K 報價的 dll 檔
SckReply T512K = new SckReply(); // SckReply 是 T512KDLL 的物件
public delegate void OnReceiveDataSCBF(string S); // 宣告用來切換執行緒的 delegate 型態
public OnReceiveDataSCBF ToOnReceiveDataSCBF; // 宣告用來切換執行緒的 delegate
bool FlagInvoke = false, FlagClose = false;
private void frmQuote_Load(object sender, EventArgs e)
{
T512K.OnReceiveDataS += new SckReply.OnReceiveDataSEventHandler(T512K_OnReceiveDataS);
ToOnReceiveDataSCBF = new OnReceiveDataSCBF(OnReceiveDataSfun);
.....................
.....................
.....................
}
private void T512K_OnReceiveDataS(string S) // 這部份是多緒在接收來自期交所的 512K 報價
{
if (FlagClose == true)
{
this.Close();
return;
}
FlagInvoke = true;
dgvQuote.Invoke(ToOnReceiveDataSCBF, S);
FlagInvoke = false;
if (FlagClose == true) this.Close();
}
private void OnReceiveDataSfun(string S)
{
// 收到期交所報價後要做的事
.....................
.....................
.....................
}
private void frmQuote_FormClosing(object sender, FormClosingEventArgs e)
{
if (FlagClose == false)
{
e.Cancel = true;
FlagClose = true;
CloseForm();
}
}
private void CloseForm() // 用來取代 Close
{
if (FlagInvoke == false)
{
this.Close();
}
}