跟踪对象在给定状态下存在的时间长度

本文关键字:存在 时间 状态 对象 跟踪 | 更新日期: 2023-09-27 18:24:20

我正在设计一个应用程序,它将创建多个Session对象可以存在两种状态:"活动"answers"非活动"。只有一个Session对象可以在任何时候处于"活动"状态,并且任何一个Session对象在其生存期内都可以在"活动"answers"非活动"之间更改任意次数。Session对象还具有TimeSpan类型的DurationActive属性,该属性表示Session处于"活动"状态的总时间。

关于如何实现这一点,有什么建议吗?

跟踪对象在给定状态下存在的时间长度

要控制其他会话对象的活动/非活动状态,请查看Mediator Pattern

http://en.wikipedia.org/wiki/Mediator_pattern

这应该允许您保持Session对象的解耦,并将交互从主代码中抽象出来

解决方案取决于您是希望通过设置属性还是通过调用方法来实现Active

我只讨论后一种选择,因为在我看来,它更容易编码(因此也更容易维护)。

您将需要MakeActive()方法(或类似方法)和MakeInactive()方法。

MakeActive()将:

  1. 检查所有其他会话是否处于非活动状态(尽管这可能——也许应该——在更高级别上处理)
  2. 启动一个Stopwatch对象,该对象将是该类的私有成员。秒表的安装时间将取决于您想要计时的时间:只是最后一次激活,还是会话生命中的总激活
  3. 使会话处于活动状态

MakeInactive()将:

  1. 使seeion处于非活动状态
  2. 停止Stopwatch对象

然后,实现TimeActive只是获取StopwatchElapsed属性的一种情况,可能带有保护,因此它只有在会话处于非活动状态时才有效。

感谢Chris关于使用Mediator模式的建议,我认为这是一个更好的解决方案。

为了控制访问,以下类将存在于它们自己的程序集中:

namespace Sessions
{
    public interface ISession
    {
        bool IsActive { get; }
        TimeSpan DurationActive { get; }
    }
    internal class Session : ISession
    {
        private Stopwatch _stopwatch;
        private bool _isChargeable;
        public bool IsActive
        {
            get { return _stopwatch.IsRunning; }
        }
        public TimeSpan DurationActive
        {
            get { return _stopwatch.Elapsed;  }
        }
        internal Session()
        {
            _stopwatch = new Stopwatch();
        }
        internal void Activate()   
        {
            _stopwatch.Start();
        }
        internal void Deactivate()
        {
            _stopwatch.Stop();
        }
    }
    public sealed class SessionMediator
    {
        private static readonly SessionMediator _instance = new SessionMediator();
        public static ISession CreateSession()
        {
            return _instance.createSession();
        }
        public static void ActivateSession(ISession session)
        {
            _instance.activateSession((Session)session);
        }
        private Session _currentSession = null;
        private SessionMediator() { }
        private ISession createSession()
        {
            return new Session();
        }
        private void activateSession(Session session)
        {
            // Deactivate the current session
            if (_currentSession != null)
                _currentSession.Deactivate();
            // Make the given session the current session
            _currentSession = session;
            // Activate the new current session
            if (_currentSession != null)
                _currentSession.Activate();
        }
    }
}

还有我的测试程序,在一个单独的程序集中:

namespace TestSessionProgram
{
    public class Program
    {
        public void Main()
        {
            ISession session1 = SessionMediator.CreateSession();
            ISession session2 = SessionMediator.CreateSession();
            ISession session3 = SessionMediator.CreateSession();
            SessionMediator.ActiveSession(session1)
            Thread.Sleep(2000);
            Debug.Assert(session1.DurationActive == TimeSpan.FromSeconds(2));
            SessionMediator.ActiveSession(session2)
            Thread.Sleep(3000);
            Debug.Assert(session2.DurationActive == TimeSpan.FromSeconds(3));
            SessionMediator.ActiveSession(session1)
            Thread.Sleep(3000);
            Debug.Assert(session1.DurationActive == TimeSpan.FromSeconds(5));
        }
    }

具有静态DateTime属性LastChange。在属性State(或函数SetActive,或其他)中,将DateTime.NowLastChange之间的差添加到DurationActive。同时将LastChange更新为DateTime.Now