まず、「評判」が 1500 以上ある人は、「ContinueWith」のタグを作成してください (この質問にタグを付けてください)。ありがとう!
この投稿が長くなって申し訳ありませんが、関連する詳細を省略したために、誰かが私を助けようとしている時間を無駄にしたくありません. とは言っても、それはまだ起こるかもしれません。:)
それでは詳細です。いくつかの ActiveMQ キュー トピックにサブスクライブするサービスに取り組んでいます。このうち 2 つのトピックは多少関連しています。1 つは「会社の更新」で、もう 1 つは「製品の更新」です。両方の「ID」は CompanyID です。会社のトピックには、製品のトピックのデータが含まれています。他のサブスクライバーは商品データを必要としているが、商品トピックをサブスクライブしたくない/必要としないため、必須です。私のサービスはマルチスレッドであるため (私たちの裁量を超えた要件)、メッセージが到着すると、更新パラメーターが単にContinueWithである AddOrUpdate を使用してConcurrentDictionaryでそれぞれを処理するTaskを追加します。(下記参照)。これらのトピックとサブスクライバーが「永続的」であるために発生する可能性のある同時更新を防ぐために行われたため、リスナー サービスがオフラインになった場合 (何らかの理由で)、同じ CompanyID に対して複数のメッセージ (会社および/または製品) で終了する可能性があります。
さて、私の実際の質問(ついに!)タスク(1つのタスクだけか、ContinueWithタスクのチェーンの最後のタスクか)が終了した後、それをConcurrentDictionaryから削除したいと思います(明らかに)。どのように?同僚のアイデアをいくつか考えてもらいましたが、どれもあまり好きではありません。あなたの答えは私が持っているが好きではないアイデアの1つである可能性があるため、アイデアをリストするつもりはありませんが、最終的には最高のものになる可能性があります.
私の説明とは異なり、スクロールしすぎないようにコード スニペットを圧縮しようとしました。:)
nrtq = 質問とは関係ありません
public interface IMessage
{
long CompantId { get; set; }
void Process();
}
public class CompanyMessage : IMessage
{ //implementation, nrtq }
public class ProductMessage : IMessage
{ //implementation, nrtq }
public class Controller
{
private static ConcurrentDictionary<long, Task> _workers = new ConcurrentDictionary<long, Task>();
//other needed declarations, nrtq
public Controller(){//constructor stuff, nrtq }
public StartSubscribers()
{
//other code, nrtq
_companySubscriber.OnMessageReceived += HandleCompanyMsg;
_productSubscriber.OnMessageReceived += HandleProductMsg;
}
private void HandleCompanyMsg(string msg)
{
try {
//other code, nrtq
QueueItUp(new CompanyMessage(message));
} catch (Exception ex) { //other code, nrtq }
}
private void HandleProductMsg(string msg)
{
try {
//other code, nrtq
QueueItUp(new ProductMessage(message));
} catch (Exception ex) { //other code, nrtq }
}
private static void QueueItUp(IMessage message)
{
_workers.AddOrUpdate(message.CompanyId,
x => {
var task = new Task(message.Process);
task.Start();
return task;
},
(x, y) => y.ContinueWith((z) => message.Process())
);
}
ありがとう!