想象以下场景:
我有这个事件:
- 登录后
- 注销前
和 AfterLogin,我有其他事件,基于可用的新/其他对象..
当用户登录时,我需要创建一个新订阅并订阅或处理它(使用其他事件)。
当用户注销时,我需要处理这些订阅并再次等待 AfterLogin
它非常类似于:
与 Rx
的值之间的巨大区别是需要一个“工厂”来创建订阅并稍后处理更多,我一开始就听不到源。
我该如何处理?
想象以下场景:
我有这个事件:
和 AfterLogin,我有其他事件,基于可用的新/其他对象..
当用户登录时,我需要创建一个新订阅并订阅或处理它(使用其他事件)。
当用户注销时,我需要处理这些订阅并再次等待 AfterLogin
它非常类似于:
与 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.