我目前有一個問題,這似乎與關閉窗體有關,而通過串行連接連接的一個秤繼續發送數據(每個包約3個包)。 。COM DataReceived事件持續激發時終止窗體。 C#
我在DataReceived事件(處理本身可能是無趣的這個問題,因爲我只是匹配的數據)留意在COM_InUse變量和allowFireDataReceived檢查)處理新的數據:
private void COMScale_DataReceived(object sender, EventArgs e)
{
if (allowFireDataReceived)
{
//set atomar state
COM_InUse = true;
//new scale:
if (Properties.Settings.Default.ScaleId == 1)
{
strLine = COMScale.ReadTo(((char)0x2).ToString());
//new scale:
Regex reg = new Regex(Constants.regexScale2);
Match m = reg.Match(strLine);
if (m.Success)
{
strGewicht = m.Groups[1].Value + m.Groups[2];
double dblComWeight;
double.TryParse(strGewicht, out dblComWeight);
dblScaleActiveWeight = dblComWeight/10000;
//add comma separator and remove zeros
strGewicht = strGewicht.Substring(0, 1) + strGewicht.Substring(1, 2).TrimStart('0') + strGewicht.Substring(3);
strGewicht = strGewicht.Insert(strGewicht.Length - 4, ",");
//write to textbox
ThreadSafeSetActiveScaleText(strGewicht);
COMScale.DiscardInBuffer();
//MessageBox.Show(dblScaleActiveWeight.ToString(), "dblScaleActiveWeight");
}
}
//free atomar state
COM_InUse = false;
}
}
COM_InUse變量是一個全局布爾值,並且「告訴」是否存在當前的數據處理過程。 allowFireDataReceived也是一個全局布爾值,如果設置爲false,將不會導致額外處理已發送的數據。現在
我的問題是這樣的:
看來Eventhandling是一個獨立的線程,這導致了僵局klicking自COM_InUse取消鍵式將永遠不會變成假的,即使事件已經被處理(請參閱COMScale_DataReceived的結尾,其中COM_InUse設置爲false)。 雖然設置allowFireDataReceived = false完美(無需處理),正如我所說:while循環不會終止。
private void bScaleCancel_Click(object sender, EventArgs e)
{
allowFireDataReceived = false;
while (COM_InUse)
{
;
}
if (!COM_InUse)
{
ret = 1;
SaveClose();
}
}
當我註釋掉while-block時,我必須點擊按鈕兩次,但它沒有崩潰。由於這個用戶不友好,我正在尋找另一種安全關閉窗口的方法。
信息: 簡單地關閉(不檢查COM數據是否被處理)會導致致命的崩潰。
所以,也許有人可以向我解釋究竟是什麼原因導致了這個問題,或者可以提供解決方案。 (也許有人會再次觸發取消點擊事件,但這非常難看)
問候!
我指望你:)
//編輯: 這裏是
private void ThreadSafeSetActiveScaleText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.lScaleActive.InvokeRequired)
{
SafeActiveScaleTextCallback d = new SafeActiveScaleTextCallback(ThreadSafeSetActiveScaleText);
this.Invoke(d, new object[] { text });
}
else
{
this.lScaleActive.Text = text;
}
}
謝謝,我希望能夠通過DiscardInBuffer()處理一個數據包(正則表達式匹配和東西)的同時,清除一些已發送的數據。 聽起來好像我沒有真正簡單的方法來處理這個問題。 順便說一句:正如我所說的,當allowFireDataReceived設置爲false時關閉秤連接工作沒有問題。 – reijin
聽起來像你只讀了答案中的最後一段。那麼你在使用Invoke嗎? –
是的,我確實使用了Invoke(在第一篇文章中添加了代碼)。 不,我看過你的整篇文章。也許我弄錯你了。我會給StartInvoke()一個嘗試。 //編輯: 所以基本上我必須使用BeginInvoke()而不是Invoke()。我有什麼需要照顧的嗎?像EndInvoke()? – reijin