0

これらのアプリケーション間の基本的なメッセージングを容易にするために、いくつかの ASP.NET MVC アプリケーション内で ServiceStack.Redis を使用しています。1 つのアプリケーション内に、サブスクリプションを設定し、アプリケーションが関心のあるメッセージを処理するクラスがあります。たとえば、次のようになります。

public MessageBus(IRedisClientsManager redisClientsManager)
{
    Thread subscriptionThread = new Thread(() => {
        try
        {
            using (var redisClient = redisClientsManager.GetClient())
            using (var subscription = redisClient.CreateSubscription())
            {
                subscription.OnMessage = (channel, message) =>
                {
                    handleMessage(message);
                };
                subscription.SubscribeToChannels("MyChannel");
            }
        }
        catch (Exception ex)
        {
            ErrorLog.GetDefault(null).Log(new Error(ex));
        }
    });
    subscriptionThread.Start();
}

「SubscribeToChannels」はブロックされているため、別のスレッドで実行しています。MVC アプリケーションが実行されている間ずっとこのスレッドを存続させたいのですが、なんらかの例外が発生した場合にスレッドが停止するか、Redis への接続が停止するのではないかと懸念しています。

私の質問は、サブスクリプションが開いている間に発生する可能性のある例外 (接続障害、タイムアウトなど) から回復する方法の例はありますか?

4

1 に答える 1

0

スレッドを強制終了する例外については、実行時間の長いループを使用してください。

while(!ShutdownRequested) {
    try{...}
    catch(Exception e) {/*Log and probably do some rate-limiting in case of terminal issue*/}
}

キャッチは OutOfMemory 例外を含むすべてを飲み込むので、常にすぐに再試行しないように、失敗カウント/遅延などの健全性チェックが必要になることに注意してください。

親からのバックグラウンド スレッドへの参照を保持し、 ThreadStateもチェックできることを忘れないでください。

ASP でのホスティングに関しては、これは悪い考えです (この回答を参照してください)。ワーカー プールがリサイクルされると (最終的には発生します)、スレッドは終了し、新しいページが (最も早く) 要求されるまで再生成されません。

サーバーの起動時に実行されるように、これを Windows サービスに配置する必要があります。サイトと通信する必要がある場合は、WCF (双方向) または Url を押す (サービスからサイトへのプッシュ)。

そうすれば、サービスが停止したときにのみ停止します(できれば再起動するだけです)。

于 2014-05-21T00:23:21.707 に答える