現在、フォームを閉じることに関連していると思われる問題が発生していますが、シリアル接続を介して接続されているスケールはデータを送信し続けます(1sekあたり約3パッケージ)。
DataReceived-Eventを介して新しいデータを処理します(データを照合しているだけなので、この問題の処理自体は面白くない可能性があります)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に設定すると、送信されたデータを余分に処理することはありません。
私の問題は次のとおりです。
イベント処理は別のスレッドのようです。これは、イベントが処理された場合でもCOM_InUseがfalseに変わることはないため、キャンセルボタンのクリックでデッドロックが発生するようです(COM_InUseがfalseに設定されているCOMScale_DataReceivedの終わりを参照)。私が言ったように、allowFireDataReceived = falseを設定している間は完全に機能します(これ以上処理しません):whileループは終了しません。
private void bScaleCancel_Click(object sender, EventArgs e)
{
allowFireDataReceived = false;
while (COM_InUse)
{
;
}
if (!COM_InUse)
{
ret = 1;
SaveClose();
}
}
whileブロックをコメントアウトするときは、ボタンを2回クリックする必要がありますが、クラッシュすることなく機能します。これは非常にユーザーフレンドリーではないので、ウィンドウを安全に閉じるための別の方法を探しています。
情報:(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;
}
}