【问题标题】:Restart InActivity Monitor after timer is stopped计时器停止后重新启动 InActivity Monitor
【发布时间】:2018-06-08 00:48:56
【问题描述】:

我有 WinForms 应用程序,我正在使用以下帖子中的代码检查我的应用程序的 InActivity 状态(请参阅帖子中接受的答案)。 InActivity In WinForms。一旦应用程序达到不活动状态,它就会停止不活动监视器。但是我想在用户登录后重新开始计时。

所以当用户登录并且我再次调用启动计时器方法时,我有一个通知机制。我收到 Started Monitor 消息,但该应用程序从不跟踪不活动状态,而且我根本没有收到 Timer 报告应用程序处于 InACTIVE 消息。请帮忙。

 public static System.Windows.Forms.Timer IdleTimer =null;
    static int MilliSeconds = 60000;
    static void Main(string[] args)
            {
                    f = new GeneStudyForm(true, arguments.SystemTimeOutFolder, arguments.SystemTimeOutFile, StartInActivityMonitor);
                    int x = StartInActivityMonitor();
            }

        public static void StartInActivityMonitor()
        {
            IdleTimer = new Timer();
            LeaveIdleMessageFilter limf = new LeaveIdleMessageFilter();
            Application.AddMessageFilter(limf);
            IdleTimer.Interval = MilliSeconds;    //One minute; change as needed
            Application.Idle += new EventHandler(Application_Idle);
            if (IdleTimer != null)
            {
                MessageBox.Show(IdleTimer.Interval.ToString());
            }
            IdleTimer.Tick += TimeDone;
            IdleTimer.Tag = InActivityTimer.Started;
            MessageBox.Show("starting");
            IdleTimer.Start();
        }

        static private void Application_Idle(object sender, EventArgs e)
                {
                    if (!IdleTimer.Enabled)     // not yet idling?
                        IdleTimer.Start();
                }

                static private void TimeDone(object sender, EventArgs e)
        {
            try
            {
                MessageBox.Show("Stopped");
                IdleTimer.Stop();   // not really necessary
                f.MonitorDirectory();
                f.UpdateInActivityStatus();
                IdleTimer.Tick -= TimeDone;
                Application.Idle -= new EventHandler(Application_Idle);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.InnerException + ex.Data.ToString());
            }
        }

这是我的 GeneStudyForm

public partial class GeneStudyForm
{
GeneStudySystemTimeOutIO GeneStudyIO;
        Func<int> StartTimer;
//Passing the StartInActivityMonitor Method as Func Delegate
public GeneStudyForm(bool isStandalone, string TimeOutFolder, string TimeOutFile, System.Func<int> MyMethod)
{
GeneStudyIO = GeneStudySystemTimeOutIO.GetInstance(TimeOutFolder, TimeOutFile);
            UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
            this.StartTimer = MyMethod;
}

public void UpdateActivityStatus(AppName name, ActivityStatus status)
        {
            if (GeneStudyIO != null)
            {
                GeneStudyIO.WriteToFile(name, status);
            }
        }
        public void MonitorDirectory()
        {
            FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(GeneStudyIO.GetDriectory());
            fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
            fileSystemWatcher.Filter = "*.json";
            fileSystemWatcher.Changed += FileSystemWatcher_Changed;
            fileSystemWatcher.EnableRaisingEvents = true;
        }

        public void UnRegister(FileSystemWatcher fileSystemWatcher)
        {
            fileSystemWatcher.Changed -= FileSystemWatcher_Changed;
        }
// I am writing the inactive status to a file. So this event will fill
        private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            try
            {
                var root = GeneStudyIO.GetDesrializedJson();
                if (root != null && root.AllApplications != null)
                {
                    var item = root.AllApplications.Any(x => x.Status == ActivityStatus.Active.ToString());
                    if (!item)
                    {
                        if (InActivecount == 0)
                        {
                            GeneStudyAndApplicationCommon.TimeStatus = InActivityTimer.Ended;
                            MessageBox.Show("I am hiding");
                            this.Hide();
                            InActivecount++;
                        }
                    }
                    else
                    {
                        if (GeneStudyAndApplicationCommon.TimeStatus == InActivityTimer.Ended)
                        {
                            MessageBox.Show("I am showing");
                            this.Show();
                            UnRegister(sender as FileSystemWatcher);
                            UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
                            MessageBox.Show("Updated Status");
                            if (StartTimer != null)
                            {
                                MessageBox.Show("Starting Timer again");
                                if (StartTimer() == -1)
                                {
                                    MessageBox.Show("Couldn't start timer");
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SystemDebugLogLogger.LogException(ex);
            }
        }
}

【问题讨论】:

  • 可以在第一次注册Idle事件处理程序的地方添加代码片段吗?我还看到您在 TimeDone 中删除了事件处理程序。你在哪里重新注册?
  • 确定我正在更新帖子
  • 还有一件事:当你删除事件处理程序时,你不应该使用 new。您应该提供一个现有的事件处理程序。
  • 当然我会尝试提供活动

标签: c# .net winforms


【解决方案1】:

这个解决方案与我发布的完全不同。但我可以用这个解决我的问题。但如果它对某人有帮助,我想发布它。这是我关注的帖子Last User Input

我创建了一个名为 IdleCheck 的类,我在其中获取 LastUserInput,如下所示

public static class IdleCheck
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct LASTINPUTINFO
        {

            [MarshalAs(UnmanagedType.U4)]

            public int cbSize;

            [MarshalAs(UnmanagedType.U4)]

            public int dwTime;

        }

        [DllImport("user32.dll")]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO x);
        public static int GetLastInputTime()
        {
            var inf = new LASTINPUTINFO();
            inf.cbSize = Marshal.SizeOf(inf);
            inf.dwTime = 0;

            return (GetLastInputInfo(ref inf)) ? Environment.TickCount - inf.dwTime : 0;
        }
    }

在实际表单中,这是我的代码。我正在使用一个简单的 yes no 消息框来查看计时器是否可以在需要时停止并再次调用。您可以应用自己的锁定机制。 如果应用程序处于非活动状态 20 秒,我希望应用程序超时。根据需要进行更改。

public partial class Form1 : Form
    {
        Timer timer;
        const int TIMEOUT_DONE = 20000;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Reset();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            //var ms = TIMEOUT_DONE - IdleCheck.GetLastInputTime();
            if (IdleCheck.GetLastInputTime() > TIMEOUT_DONE)
            {
                DialogResult dialogResult = MessageBox.Show("Sure", "Some Title", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    Stop();
                    Reset();
                }

            }

        }

        public void Reset()
        {
            timer = new Timer();

            timer.Interval = 10000;

            timer.Tick += timer_Tick;

            timer.Start();
        }

        public void Stop()
        {
            timer.Tick -= timer_Tick;
            timer.Stop();
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多