テキストの複数のパッセージから単語を並行してカウントする方法を備えた C# ライブラリを作成しました。getnextchar()
テキストのパッセージは、呼び出されるたびにランダムな遅延がある文字ストリームとして与えられます。私のライブラリ メソッドは、これらの文字ストリームの配列を取得し、結合された単語頻度カウントを返す必要があります。これを行うために、安全に共有される単語頻度データ構造と、各文字ストリームを読み取って共有コレクションを更新するスレッドを用意しました。すべてのスレッドが完了したら、データ構造をクライアント アプリケーションに返します。
クライアント アプリケーションは、10 秒ごとに合計単語カウントの中間結果を必要とします。これを行うために、デリゲートを使用して、すべてのワーカー スレッドが完了するまで 10 秒ごとに結果をクライアントにコールバックし、その後、最終結果をクライアントに返します。
私の問題は、中間結果でクライアントをコールバックするときに、共有データ構造をロックし、ロックを解除する前にクライアント アプリケーションがコールバックから戻るのを待つ必要があることです。コールバックが実行されている間、すべてのワーカー スレッドはブロックされ、データ構造のロックを待機します。これは賢明なことではないように思えます。なぜなら、クライアント コードがすぐに返されるか、まったく返されないことに依存したり、信頼したりする必要があるとは思わないからです。ただし、クライアント コードに依存しない他の唯一の方法は、データ構造のコピーまたはスナップショットを作成し、それをコールバックを介してクライアントに渡すことです。これはメモリと計算を犠牲にしますが、コピーが作成されると、ワーカーは共有コレクションを更新し続けることができ、コールバックは必要なことを何でも行うことができます。
私の質問は2つあります:
1) 悪いクライアント コールバック実装がワーカーをブロックする可能性を許すか、定期的にコストのかかる操作を実行する可能性があるという 2 つの悪のうち、どちらが小さいか。
2)上記のいずれも行わないこの問題を解決する方法はありますか?