これは私の最初のC#プロジェクトですので、以下のコードで明らかに不適切なことを行っている可能性があります。 私は.NET、WinForms(私は思う)を使用しています。これはバグを出すまではデスクトップアプリケーションです。 UpdateGui()
はInvoke((MethodInvoker)delegate
を使用して、受信したシリアルデータに基づいてさまざまなGUIコントロールを更新し、 はGetStatus()
コマンドをシリアルポートから1秒間に4回送信します。 スレッドRead()
は、到着するたびにシリアルポートから応答を読み取ります。 SerialPortFixer
はSerialPort
IOException
です。C#の回避策は、 http://zachsaw.blogspot.com/2010/07/serialport-ioexception-workaround-in-c.htmlです。なぜC#スレッドが死んでいるのですか?
いずれかまたは両方のスレッドが終了した後、 The thread 0x1288 has exited with code 0 (0x0)
のようなものが表示されます。デバッグコードの出力に
なぜUpdateGui()および/またはRead()は最終的に死ぬのですか?あなたがスレッドのリターンを作成するときの方法は、指定したときに、より具体的に実行、またはするこれ以上のコードがないとき
public partial class UpdateStatus : Form
{
private readonly byte[] Command = new byte[32];
private readonly byte[] Status = new byte[32];
readonly Thread readThread;
private static readonly Mutex commandMutex = new Mutex();
private static readonly Mutex statusMutex = new Mutex();
...
public UpdateStatus()
{
InitializeComponent();
SerialPortFixer.Execute("COM2");
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
try
{
serialPort1.Open();
}
catch (Exception e)
{
labelWarning.Text = LOST_COMMUNICATIONS + e;
labelStatus.Text = LOST_COMMUNICATIONS + e;
labelWarning.Visible = true;
}
readThread = new Thread(Read);
readThread.Start();
new Timer(UpdateGui, null, 0, 250);
}
static void ProcessStatus(byte[] status)
{
Status.State = (State) status[4];
Status.Speed = status[6]; // MSB
Status.Speed *= 256;
Status.Speed += status[5];
var Speed = Status.Speed/GEAR_RATIO;
Status.Speed = (int) Speed;
...
}
public void Read()
{
while (serialPort1 != null)
{
try
{
serialPort1.Read(Status, 0, 1);
if (Status[0] != StartCharacter[0]) continue;
serialPort1.Read(Status, 1, 1);
if (Status[1] != StartCharacter[1]) continue;
serialPort1.Read(Status, 2, 1);
if (Status[2] != (int)Command.GetStatus) continue;
serialPort1.Read(Status, 3, 1);
...
statusMutex.WaitOne();
ProcessStatus(Status);
Status.update = true;
statusMutex.ReleaseMutex();
}
catch (Exception e)
{
Console.WriteLine(@"ERROR! Read() " + e);
}
}
}
public void GetStatus()
{
const int parameterLength = 0; // For GetStatus
statusMutex.WaitOne();
Status.update = false;
statusMutex.ReleaseMutex();
commandMutex.WaitOne();
if (!SendCommand(Command.GetStatus, parameterLength))
{
Console.WriteLine(@"ERROR! SendCommand(GetStatus)");
}
commandMutex.ReleaseMutex();
}
private void UpdateGui(object x)
{
try
{
Invoke((MethodInvoker)delegate
{
Text = DateTime.Now.ToLongTimeString();
statusMutex.WaitOne();
if (Status.update)
{
if (Status.Speed > progressBarSpeed.Maximum)
{
Status.Speed = progressBarSpeed.Maximum;
}
progressBarSpeed.Value = Status.Speed;
labelSpeed.Text = Status.Speed + RPM;
...
}
else
{
labelWarning.Text = LOST_COMMUNICATIONS;
labelStatus.Text = LOST_COMMUNICATIONS;
labelWarning.Visible = true;
}
statusMutex.ReleaseMutex();
GetStatus();
});
}
catch (Exception e)
{
Console.WriteLine(@"ERROR! UpdateGui() " + e);
}
}
}
あなたのためにあなたのプログラムをデバッグすることを真剣におねがいしますか? –
いいえ、私は数日間それをハッキングしていました。おそらく、私はC#に詳しい方には明らかないくつかの練習に違反しています。 – jacknad
スレッド終了メッセージがいずれかのスレッドに関連付けられていると仮定しているのはなぜですか? –