ネットワークまたはシリアルポートからデータを取得するスレッドがあります。5 秒以内にデータが受信されない場合、スレッドは終了する (または false を返す) 必要があります。
つまり、スレッドの実行に 5 秒以上かかる場合は停止する必要があります。
私は C# で書いていますが、.NET 言語なら何でも構いません。
ネットワークまたはシリアルポートからデータを取得するスレッドがあります。5 秒以内にデータが受信されない場合、スレッドは終了する (または false を返す) 必要があります。
つまり、スレッドの実行に 5 秒以上かかる場合は停止する必要があります。
私は C# で書いていますが、.NET 言語なら何でも構いません。
次の 2 つの方法があります。
ネットワークまたはシリアルポートからデータを読み取るスレッドは、開始時刻からの経過時間を測定し、残りの時間だけデータを待機できます。通常、ネットワーク通信 API は、操作のタイムアウトを指定する手段を提供します。したがって、単純なDateTime
計算を行うことで、ワーカー スレッド内でタイムアウト管理をカプセル化できます。
別のスレッドを使用して (または可能であればメイン スレッドで実行して)、ワーカー スレッドが特定の制限時間内に終了するのを待ち、そうでない場合は中止します。このような:
// start the worker thread
...
// give it no more than 5 seconds to execute
if (!workerThread.Join(new TimeSpan(0, 0, 5)))
{
workerThread.Abort();
}
推奨事項:クリーンで保守しやすい設計につながるため、最初の解決策に固執します。ただし、特定の状況では、そのようなワーカー スレッドの「ハード」アボートの手段を提供する必要がある場合があります。
どちらのメカニズムでも、読み取り時にタイムアウトを指定できるはずです。たとえばNetworkStream.ReadTimeout
、読み取りを実行する前に 5000 に設定できます。シリアルポートでも同様のことができるはずです。
タイムアウトした読み取りは 0 を返します。Stream.Read()
これは、タイムアウトが実際に発生したかどうかを知る方法です。
Thread.Abort()
usingは、深刻な問題を引き起こす可能性があるため、.NET 2.0 以降では推奨されていないことに注意してください。理論的Thread.Interrupt()
には を使用できますが、スレッドがアンマネージ コード (I/O を含む) でブロックされている場合、これは何もしません。この問題を解決するには、読み取りタイムアウトを使用するのが適切な方法です。
マネージコードを使用してスレッドをブロックしている場合は、を使用Thread.Abort
して実行を中止できます。サードパーティのコードまたはCOM相互運用機能を使用している場合、スレッドの実行を終了する方法はありません。唯一の方法は、Thread.isBackroundThread
をtrueに設定してから、プロセスを終了することです。
これは 2 スレッドのソリューションです。
Thread tParent = new Thread(new ThreadStart(() =>
{
Thread t = new Thread(AsyncMethod);
t.Start();
Thread.Sleep(5000);
if (t.IsAlive) t.Abort();
}));
このような方法を使用するのは悪い習慣です。通話Thread.Abort()
は推奨されません。代わりにThread Synchronization
using を使用してください。WaitHandles
たとえば、AutoResetEvent
.
あなたは「ネットワーク」から読んでいると言いました。NetworkStream
読み取りに使用している場合は、ReadTimeout
を 5000 (ミリ秒単位) に指定できます。5 秒間待機し、その後、データが読み取られていない場合は戻ります。ただし、途中や読み込み中の場合は戻ってくることもあると思いますので気をつけてください。シリアル API で何もしたことがないので、そのような設定があるかどうかはわかりません。
ウォッチャースレッドが必要だと思います。同時に別のスレッドを開始し、シリアル ポート スレッドをそのスレッドのパラメーターとして渡します。ウォッチャーを 5 秒間スリープさせて開始し、スレッドのステータスを確認します。
スレッドの終了については、アレックスの答えを参照してください。