创建可观察且仅在事件之间使用



想象一下以下场景:

我有这个事件:

  • 登录后
  • 注销前

登录后,我还有其他事件,基于新的/其他可用的对象。

当用户登录时,我需要创建一个新订阅并订阅或处理它(使用其他事件)。
当用户注销时,我需要处理这些订阅并再次等待登录后

它非常类似于:在带有 Rx 的值之间
需要"工厂"来创建订阅并在以后处理更多内容的巨大差异,我一开始就听不到消息来源。

我该如何处理?

由于您没有提供任何代码,并且规范有点模糊,因此很难给出特定的代码示例,因此这有点斗志昂扬。

但也许它会提供一些灵感或引导你回答一个更具体的问题。发布一些您尝试过的内容总是有帮助的!

代码为您提供了一个非终止流,该流在所有会话中承载登录用户生成的所有事件。

public class LoggedInActivity
{
    [Test]
    public void TestLoggingIn()
    {
        var sessionManager = new SessionManager();
        var afterLogIn = Observable.FromEventPattern<SessionEventArgs>(
            h => sessionManager.AfterLogin += h,
            h => sessionManager.AfterLogin -= h)
            .Select(x => x.EventArgs.UserId);
        var beforeLogOff = Observable.FromEventPattern<SessionEventArgs>(
            h => sessionManager.BeforeLogoff += h,
            h => sessionManager.BeforeLogoff -= h)
            .Select(x => x.EventArgs.UserId);
        var loggedIn = afterLogIn.GroupByUntil(
            userId => userId,
            login => beforeLogOff.Where(y => y == login.Key));
        Func<IGroupedObservable<int, int>, IObservable<string>> whileLoggedIn = login =>
            Observable.Using(
                () => sessionManager.AddSession(new Session(login.Key)),
                session => Observable.FromEventPattern(
                    h => session.SomeEvent += h,
                    h => session.SomeEvent -= h)
                    .Select(x => "User " + login.Key + " had SomeEvent!")
                    .TakeUntil(login.LastAsync()));
        // Single non-terminating stream that captures
        // all events occuring during any login 
        var loggedInEvents = loggedIn.SelectMany(whileLoggedIn);
        loggedInEvents.Subscribe(Console.WriteLine);
        sessionManager.Login(1);
        sessionManager.Sessions[1].RaiseSomeEvent();
        sessionManager.Login(2);
        sessionManager.Sessions[1].RaiseSomeEvent();
        sessionManager.Sessions[2].RaiseSomeEvent();
        sessionManager.Logoff(2);
        sessionManager.Logoff(1);
    }
}
public class SessionManager
{
    public event EventHandler<SessionEventArgs> AfterLogin;
    public event EventHandler<SessionEventArgs> BeforeLogoff;
    private readonly Dictionary<int, Session> _sessions = new Dictionary<int, Session>();
    public Dictionary<int, Session> Sessions { get { return _sessions; } }
    public void Login(int userId)
    {
        var temp = AfterLogin;
        if (temp != null)
        {
            AfterLogin(this, new SessionEventArgs(userId));
        }
    }
    public Session AddSession(Session session)
    {
        _sessions.Add(session.UserId, session);
        return session;
    }
    public void Logoff(int userId)
    {
        var temp = BeforeLogoff;
        if (temp != null)
        {
            BeforeLogoff(this, new SessionEventArgs(userId));
        }
        Sessions.Remove(userId);
    }
}
public class Session : IDisposable
{
    private readonly int _userId;
    public int UserId { get { return _userId; } }
    public Session(int userId)
    {
        _userId = userId;
        Console.WriteLine("User " + _userId + " logged in.");
    }
    public event EventHandler SomeEvent;
    public void RaiseSomeEvent()
    {
        var temp = SomeEvent;
        if (temp != null)
        {
            SomeEvent(this, EventArgs.Empty);
        }
    }
    public void Dispose()
    {
        Console.WriteLine("User " + _userId + " logged out.");
    }
}
public class SessionEventArgs : EventArgs
{
    private readonly int _userId;
    public SessionEventArgs(int userId)
    {
        _userId = userId;
    }
    public int UserId { get { return _userId; } }
}

会话实例及其事件的可观察流在登录时创建,并在注销时释放。

运行测试的输出为:

User 1 logged in.
User 1 had SomeEvent!
User 2 logged in.
User 1 had SomeEvent!
User 2 had SomeEvent!
User 2 logged out.
User 1 logged out.

相关内容

  • 没有找到相关文章

最新更新