2

Service Stack を使用して Redis に接続し、SubPub 機能を使用しています。

IRedisSubscription と IRedisClient のインスタンス化を維持する必要がありますか? たとえば、クラス レベルの変数に割り当てる必要がありますか?

または、using ステートメント内で単純にスコープを設定して、サービス スタックが永続性を処理することはできますか?

つまり、次の例のうち正しいものはどれですか。

public class RedisPubSub1 : IDisposable {

    private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString");
    private IRedisSubscription _subscription;
    private IRedisClient _client;

    private Action<string, string> _publish;
    public event Action<string, string> Publish {
        add { _publish += value; }
        remove { _publish -= value; }
    }

    public RedisPubSub1()
    {         
        Task.Factory.StartNew(() =>
            {
                _client = ClientPool.GetClient();
                _subscription = _client.CreateSubscription();
                    {
                        _subscription.OnMessage = EnqueEvent;
                        _subscription.SubscribeToChannels(new string[] { Channel });
                    }
        });
    }

    private void EnqueEvent(string channel, string message)
    {
        if (_publish!= null)
            _publish(channel, message);
    }      

    public void Dispose()
    {
        _subscription.Dispose();
        _client.Dispose();


    }
} }

または

パブリック クラス RedisPubSub2 {

    private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString");

    private Action<string, string> _publish;

    public event Action<string, string> Publish {
        add { _publish += value; }
        remove { _publish -= value; }
    }

    public RedisPubSub2()
    {         
        Task.Factory.StartNew(() =>
            {
                using(var _client = ClientPool.GetClient())
                {
                    using(_subscription = _client.CreateSubscription()
                    {
                        _subscription.OnMessage = EnqueEvent;
                        _subscription.SubscribeToChannels(new string[] { Channel });
                    }
                }
        });
    }

    private void EnqueEvent(string channel, string message)
    {
        if (_publish!= null)
            _publish(channel, message);
    }       }
4

1 に答える 1

2

SubscribeToChannels はブロックされているため、接続への参照を保持するかどうかは問題ではありません。サブスクリプションを終了しない限り (つまり、サブスクライブを解除しない限り) 破棄されないためです。

RedisMqServer の例に見られるように、アクティブなサブスクリプションを保持しているスレッドで実行したい場合に、サブスクリプションからサブスクリプションを解除する何らかの方法を実装することをお勧めします。

using (var subscription = redisClient.CreateSubscription())
{
    subscription.OnUnSubscribe = channel => 
       Log.Debug("OnUnSubscribe: " + channel);

    subscription.OnMessage = (channel, msg) =>
    {
        if (msg == "STOP")
        {
            Log.Debug("UnSubscribe From All Channels...");
            subscription.UnSubscribeFromAllChannels(); //Un block thread.
            return;
        }

        handleMessage(msg);
    }   

    ...

    //Unsubscribing will unblock this subscription:
    subscription.SubscribeToChannels(QueueNames.TopicIn); //blocks thread
}
于 2013-06-24T16:39:36.610 に答える