問題タブ [waithandle]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 待機ハンドルを結合しますか?
ここでちょっと面白いと思います。多数の処理操作を固定数のスレッドに「多重化」するクラスがあります。典型的なケースは一種のプロデューサー/コンシューマーの問題であり、各操作は WaitHandle (この場合、キューにあるアイテムの数を追跡するセマフォ) と呼び出すデリゲートで構成されます。
たとえば、2 つのプロデューサー (A と B) があり、アイテムを 2 つの個別のキューに生成するとします。プロデューサ (A1、A2、B1、B2) ごとに 2 つのコンシューマ スレッドを作成するのではなく、4 つのコンシューマ「スレッド」を 2 つのスレッドに多重化しています。この「マルチプレクサ」のコードは、次のように実行されます (少し簡略化されています)。
この概念をもう少し複雑な例に拡張しようとしています。この例では、アクションが実行される前に複数の待機ハンドルを満たす必要がある場合があります。2 つの待機ハンドルを 1 つの待機ハンドルに結合するために行うことができる、ある種の WaitHandle.Combine(waitHandle1, waitHandle2) 呼び出しがあるかどうか疑問に思っています。最終結果は次のようになります。
エクストラポイント?
必須ではありませんが、待機ハンドルの組み合わせが交差できると非常に便利です。たとえば、次のようなものです。
助けてくれてありがとう
vb.net - WaitHandle.WaitAll すべてのスレッドが完了する前に実行される - VB.Net 4.0
サーバーのリストをスキャンしてさまざまな情報を取得するプログラムに取り組んでいます。
スレッドが完了したときに時々エラーが発生することを除いて、すべてが正常に機能しています。スキャンが完了するか、キャンセル ボタンがループを停止し、現在のスレッドを続行します。
スキャンが完了したことを示す UI が表示されますが、progressUpdate は再度実行を試みます。waitall の後に thread.sleep を長くすることで問題を解決できます。
ほとんどの場合、最後のスレッドまで待機しますが、OperationsComplete が既に実行されているため、progressUpdate 関数にアクセスできないというエラーが表示されることがあります。
以下の BackgroundWorker1.ReportProgress(_completedCount, ScanResult) でエラーが発生しますが、WaitAll はスレッドが完了するまで待機する必要があるため、それを呼び出すべきではありません。
編集配列を壊すと空になります。しかし、どういうわけかまだ何かが動いています。多分私は1つを捕まえることを逃しています。
c# - スレッドが待機する WaitHandle を実行時に置き換える方法
スレッドが待機する EventWaitHandle を実行時に安全に変更する方法を考えています。
たとえば、EventWaitHandles を介して同期される 2 つのスレッド (A と C) があるとします。A はそのジョブを周期的に実行し、C は A からそのジョブの実行を開始できるという通知を受信するまで (たとえば、AutoResetEvent によって) 待機します。柄はACAC...
その後、新しいスレッド (B) が起動され (たとえば、ユーザーの操作によって)、そのジョブは 2 つの既存のスレッドの間で次のように実行される必要があります。パターンはABCABC...
したがって、スレッド C が A と共有される EventWaitHandle を待機する前に、後で C が B と共有される別の EventWaitHandle を待機するようにする安全なメカニズムが存在する必要があります。 EventWaitHandle を使用して A ジョブを待機し、EventWaitHandle を使用して C ジョブを通知する B を簡単に起動できるはずです。このメカニズムは、スレッド B を安全にアンマウントし、スレッド A と C のみが動作している初期状態に戻る方法も提供する必要があります。
EventWaitHandle でこれを達成する安全な方法はありますか? そうでない場合は、他の提案をいただければ幸いです。
c# - マルチスレッド:WaitAllは期待どおりに待機しません
何かをするために2つの別々のスレッドを呼び出しているスレッドがあります。いずれかのジョブが終了するたびに、Waithandle.Set(0が呼び出され、親ワーカースレッドの最後で、続行する前に両方が終了するまでWaitAllが必要でした。ただし、priceA()が最初に表示され、次にPriceBが表示されます。 ()。
私は何が欠けていますか?
アップデート:
Ctor:
c# - 周期的で変化しやすいアクション フローを処理するのに最適なコード パターンはどれですか
私のシナリオは、リアルタイム データを周期的に処理し、締め切りが厳しいアプリケーションです。
各サイクルでデータに対して実行する一連のアクションがあります。各サイクルで実行されるアクション ( A、B、C .. などの大文字で呼び出しましょう) と x サイクルごとにのみ実行されるその他のアクション ( d、e、fなどの小文字で呼び出しましょう) があります。...)。2 つの永続的なアクションと 3 サイクルの期間で実行される 1 つのフロー パターンの例は、次のようになります (サイクルの終わりは「|」でマークされます)。
A - B - d | A - B | A - B | A - B - D |...
さらに、パターンはユーザーの入力に応じて実行時に変更される可能性があります。そのため、いくつかのアクションをリストに追加または削除できます。たとえば、Bを削除し、 A の後にCを追加し、Cの後にeを 2 サイクルの期間で追加することによる前のパターンは、突然次のようになります ('->' でマークされたサイクルを変更):
...| A - B - d | -> A - D - C - E | A - C | A - C - e | A - D - C | A - C - e | A - C | A - D - C - E |...
現在、WaitHandles を介して相互に通信するスレッドを手動で開始し、アクションが重い場合は Parallel.For を利用します。次に、パターンが変更されたときに、たとえば特定のスレッドを終了し、別のスレッドを起動し、待機する WaitHandle を置き換える必要がある場合があります...パターンが変更されたときに発生するデッドロックの問題があります。それらを修正することはできましたが、後でパターンを変更する必要がある場合に備えて、効率的にそれを行うためのすべてのツールを既に持っているので、より柔軟なソリューションを用意する方がはるかに良いという考えに至りました。
私はこのトピックについてはかなり新しいですが、(以前に提案されたことにも従って)一種のスケジューラが必要だと思います。
Windows Workflow Foundation (現時点では、それが自分の状況に適しているかどうかはわかりません) やその他のソリューションについて読んだことがありますが、時間をかけて理解する前に、取るべき最善の方向性を知る必要があります。たとえば、タスクはこれにより適していますか? または、スレッドに固執して、考えられるすべての状況を管理するための Scheduler クラスを作成する必要があります (この場合、パターンの変更に関するさまざまな問題が既に発生しており、問題をより深く掘り下げていただければ幸いです)。または、より良い代替手段がありますか?
[編集]サイクル内
の前のメイン アクション ( A、B、...) が終了したときに、アクションを実行できます。マイナー アクション ( d、e、...) は同時に実行できます。たとえば、タイプA -B -d -eのサイクルでは、アクションBはA の後にのみ実行でき、アクションdはBの後にのみ実行でき、アクションeはBの後にのみ実行でき、場合によってはdと同時に実行することもできます。さらに、2 つの連続するメイン アクションをグループ化しない場合 (この例では、AおよびBは、相互依存性があるため、1 つのアクションにグループ化できます)。これは、2 つの異なるスレッドで実行されることを意味します。この理由は、中間結果を格納するために循環バッファーを使用しているためです (この例では、結果はAから取得され、後でBによって使用されます)。バッファーは、何らかの理由でプロセスに遅延が発生した場合に、リアルタイム プロセス中にデータを失わないようにするのに役立ちます (実際、メイン リーダー アクションAは、サイクルの最後のアクションが終了したかどうかに関係なく、常に良好なタイミング精度で発生します。いいえ)。
.net - .net-IPC-最初に起動する最も古いプロセスの作業を「キューに入れる」
データを処理し、Crystal Reportsを生成し、レンダリングされた出力をプリンターに送信する.Net2.0アプリケーションがあります。このアプリケーションは、ほとんどの場合、Win32アプリケーションから複数回起動されます。レンダリングされたレポートを実際にプリンタに送信するのにかかる時間は、データのサイズやCrystalReportの複雑さによって異なります。私の悩みの種は、レポートを印刷する準備
ができて
いるかどうかに関係なく、プロセスと同じ順序で印刷ジョブをキューに入れる必要があるということです。したがって、たとえば:
上記の例では、プロセス1で最初に印刷し、次にプロセス2、次にプロセス3で印刷する必要があります。ただし、レポートの印刷のみを順番に実行する必要があります。すべての「咀嚼」を同時に実行できます。
私はMutexとSemaphoreをいじっていますが、テストアプリでは、最初のプロセスが最初に「印刷」されますが、2番目と3番目(4番目、5番目など)はそれに応じて「印刷」されます。彼らの「WaitOne」が発行されたとき。
私はここで間違ったルートを進んでいますか?
私が必要としているのは、IPCの「キューに入れられたWaitHandle」のようなメカニズムのようなものだと思います...
.net - bool で WaitHandle を使用してキャンセルのフラグを立てる理由はありますか?
私はスレッド化されたコードを少し継承しました。それを確認すると、(バックグラウンド スレッド メソッド内で) 次のような構造が見つかりました。
Stop()通常、次のようなpublic または private メソッドがあります。
私の質問は次のとおりです。ここで待機ハンドルを使用すると、何が提供されますか? これは、停止のシグナリングがアトミック操作であることを保証するために行われているようですが、ブール値への書き込みはとにかくアトミックだと思いました。その場合、以下を使用しない理由はありますか。
c# - ロックの代わりに WaitHandle を使用する必要がある場合
では、いつ ?の代わりにC#使用する必要がありますか?WaitHandlelock
c# - AutoResetEvent オブジェクトで WaitOne メソッドを呼び出したスレッドのブロックを解除するにはどうすればよいですか?
以下は、私の問題を示すメソッド「SomeMethod」を持つクラスです。
このメソッドはスレッドセーフになるように設計されており、異なるスレッドで呼び出されます。ここで私の質問は、いつでも「theEvent」オブジェクトで「WaitOne」メソッドを呼び出したすべてのスレッドのブロックを解除する方法です。マルチスレッド プログラムを正常に停止および開始できるようにする必要があるため、この要件は私の設計で頻繁に発生します。マルチスレッド プログラムを開始するのはかなり簡単ですが、停止するのは難しいように思えます。
これが私がこれまでに試したもので、明らかにうまくいきます。しかし、これは標準的なアプローチですか?
「UnblockAll」メソッドは、「SomeClass」クラスのメンバーです。ここで使用する手法は、WaitOne メソッドの MSDN ドキュメントに基づいています。以下のドキュメントの関連部分を引用しています。
millisecondsTimeout がゼロの場合、メソッドはブロックされません。待機ハンドルの状態をテストし、すぐに戻ります。
do..while ループでSet メソッドを呼び出します。これにより、WaitOne メソッド (「SomeMethod」メソッド内にコード化されている) への呼び出しが原因でブロックされた可能性がある単一のスレッドが解放されます。次に、'theEvent' オブジェクトの状態をテストして、シグナル状態かどうかを確認します。このテストは、タイムアウト パラメータを受け取る WaitOne メソッドのオーバーロードされたバージョンを呼び出すことによって行われます。WaitOne メソッドを呼び出すときに使用する引数はゼロです。ドキュメントによると、呼び出しはブール値ですぐに返されます。戻り値が true の場合、「theEvent」オブジェクトはシグナル状態です。「SomeMethod」メソッドの「WaitOne」メソッドの呼び出しで少なくとも 1 つのスレッドがブロックされていた場合、「Set」メソッド (「UnblockAll」メソッド内にコード化されている) の呼び出しによってブロックが解除されます。したがって、'UnblockAll' メソッドの do..while ステートメントの最後にある 'WaitOne' メソッドの呼び出しは false を返します。ブロックされたスレッドがない場合にのみ、戻り値は true になります。
上記の推論は正しいですか? また、正しい場合、その手法は私の問題に対処するための標準的な方法ですか? 主に .net コンパクト フレームワーク 2.0 プラットフォームでソリューションを使用しようとしています。
c# - 待機ハンドルを使用した条件付き定期タイマー
特定のアクションを定期的に実行する同等のタイマーが必要です (たとえば、データベースの進行状況を更新したり、データベースで実行する新しいジョブをチェックしたりします)。
これらのアクションは、ジョブを実行する必要があるかどうかを指定する WaitHandle にバインドされます。したがって、基本的にこれは、たとえば、データベースに新しいエンティティがあり、これらの新しいエンティティの検索をトリガーするときに外部から設定される AutoResetEvent である可能性があります。データベースへのクエリの数を制限したいので、タイマーが必要です。したがって、10 個の新しい通知が届いた場合、AutomaticResetEvent は 1 回だけ設定され、これらすべてに対して 1 つのクエリのみが存在します。
私の最初の試みは次のようになります。
このアプローチの問題は、WaitHandle.WaitAny がトリガーされた最初の WaitHandle のインデックスのみを提供することです。したがって、トリガーされる WaitHandles が 2 つ以上ある場合、最初のアクションのみを実行し、他のアクションは実行しません。
指定された期間内にトリガーされたすべてのアクションを実行するために必要な結果を達成するためのより良い設計はありますか? 問題を単純化する場合は、WaitHandles の代わりに別の種類の通知メカニズムを使用できます。
ありがとう!