14

ネットワークまたはシリアルポートからデータを取得するスレッドがあります。5 秒以内にデータが受信されない場合、スレッドは終了する (または false を返す) 必要があります。

つまり、スレッドの実行に 5 秒以上かかる場合は停止する必要があります。

私は C# で書いていますが、.NET 言語なら何でも構いません。

4

6 に答える 6

9

次の 2 つの方法があります。

1. カプセル化されたタイムアウト

ネットワークまたはシリアルポートからデータを読み取るスレッドは、開始時刻からの経過時間を測定し、残りの時間だけデータを待機できます。通常、ネットワーク通信 API は、操作のタイムアウトを指定する手段を提供します。したがって、単純なDateTime計算を行うことで、ワーカー スレッド内でタイムアウト管理をカプセル化できます。

2. 外部タイムアウト

別のスレッドを使用して (または可能であればメイン スレッドで実行して)、ワーカー スレッドが特定の制限時間内に終了するのを待ち、そうでない場合は中止します。このような:

// start the worker thread
...

// give it no more than 5 seconds to execute
if (!workerThread.Join(new TimeSpan(0, 0, 5)))
{    
    workerThread.Abort();
}

推奨事項:クリーンで保守しやすい設計につながるため、最初の解決策に固執します。ただし、特定の状況では、そのようなワーカー スレッドの「ハード」アボートの手段を提供する必要がある場合があります。

于 2010-12-21T17:10:38.643 に答える
4

どちらのメカニズムでも、読み取り時にタイムアウトを指定できるはずです。たとえばNetworkStream.ReadTimeout、読み取りを実行する前に 5000 に設定できます。シリアルポートでも同様のことができるはずです。

タイムアウトした読み取りは 0 を返します。Stream.Read()これは、タイムアウトが実際に発生したかどうかを知る方法です。

Thread.Abort()usingは、深刻な問題を引き起こす可能性があるため、.NET 2.0 以降では推奨されていないことに注意してください。理論的Thread.Interrupt()には を使用できますが、スレッドがアンマネージ コード (I/O を含む) でブロックされている場合、これは何もしません。この問題を解決するには、読み取りタイムアウトを使用するのが適切な方法です。

于 2010-12-21T17:07:38.073 に答える
3

マネージコードを使用してスレッドをブロックしている場合は、を使用Thread.Abortして実行を中止できます。サードパーティのコードまたはCOM相互運用機能を使用している場合、スレッドの実行を終了する方法はありません。唯一の方法は、Thread.isBackroundThreadをtrueに設定してから、プロセスを終了することです。

于 2010-12-21T17:03:28.890 に答える
2

これは 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 Synchronizationusing を使用してください。WaitHandlesたとえば、AutoResetEvent.

于 2010-12-21T17:12:24.270 に答える
2

あなたは「ネットワーク」から読んでいると言いました。NetworkStream読み取りに使用している場合は、ReadTimeoutを 5000 (ミリ秒単位) に指定できます。5 秒間待機し、その後、データが読み取られていない場合は戻ります。ただし、途中や読み込み中の場合は戻ってくることもあると思いますので気をつけてください。シリアル API で何もしたことがないので、そのような設定があるかどうかはわかりません。

于 2010-12-21T17:10:03.963 に答える
1

ウォッチャースレッドが必要だと思います。同時に別のスレッドを開始し、シリアル ポート スレッドをそのスレッドのパラメーターとして渡します。ウォッチャーを 5 秒間スリープさせて開始し、スレッドのステータスを確認します。

スレッドの終了については、アレックスの答えを参照してください。

于 2010-12-21T17:04:22.027 に答える