Modbusプロトコルを使用してハードウェア コントローラーに C# ラッパーを作成しています。
コントローラには 12 の入力と 12 の出力があります。
ラッパーには 2 つのタスクがあります
。 1. コントローラの入力を一定の間隔 (つまり 50ms) でポーリングします。
2. コントローラの出力を変更する事前設定されたシーケンスを実行します。
シーケンスは XML ベースです。
<opcode>
<register>0</register>
<bit>1</bit>
<duration>500</duration>
</opcode>
<opcode>
<register>0</register>
<bit>0</bit>
<duration>0</duration>
</opcode>
....
上記のサンプルでは、コントローラーは出力 #0 をオンにし、500ms 後にオフにする必要があります。
操作間の一時停止は、 を使用して達成されましThread.Sleep()
た。
過去に、BackgroundWorker を 1 つだけ使用しました。シーケンスを実行していないときは、ポーリングを行いました。
課題:
ラッパーに対する新しい要求は、シーケンスの実行中にコントローラーの入力の変化を検出できることです。
ラッパーを変更して、2 つのバックグラウンド ワーカー (1 つはポーリング用、もう 1 つは出力レジスタの設定用) を持つようにしました。
各 BackgroundWorkers はコントローラーで個別の関数を呼び出しますが、お互いのデータにアクセスしようとしたり、データを共有したりすることはありません。
現在のコード:
private void workerSequence_DoWork(object sender, DoWorkEventArgs e)
{
if (!terminating)
if (e.Argument != null)
DoSequence(e);
}
private void workerPoll_DoWork(object sender, DoWorkEventArgs e)
{
if (!terminating)
{
DoPoll();
Thread.Sleep(pollInterval);
}
}
private void DoSequence(DoWorkEventArgs e)
{
string sequenceName = e.Argument.ToString();
foreach (configurationSequencesSequenceOpcode opcode in sequencesList[sequenceName])
{
if (workerSequence.CancellationPending)
break;
byte register = opcode.register;
bool bit = opcode.bit;
int duration = opcode.duration;
SetRegister(register, bit, false);
Thread.Sleep(duration);
}
e.Result = e.Argument;
}
問題:
2 つの BackgroundWorker が互いに干渉しているようです。Semaphore
を使用しMonitor.Wait()
てみましManualResetEvent.WaitOne()
たが、シーケンスを処理する BackgroundWorker がうまく処理できません。主な問題 - スリープ時間は以前と同じではありません。
どんなアドバイスでも大歓迎です。