线程调度程序在WPF中休眠

本文关键字:休眠 WPF 调度程序 线程 | 更新日期: 2023-09-27 18:18:05

我正在尝试创建一个Kinect + WPF应用程序。Kinect部分运行良好;现在我想创建一个方法来检查页面是否空闲(在特定的时间内没有用户与程序交互)。如果空闲时间超过5秒,屏幕将被锁定。算法如下:

  1. 启动线程(我需要使用Dispatcher作为线程需要修改WPF元素)
  2. 检查用户是否正在使用。如果没有,则增加1。
  3. 如果Count == 9(这意味着已经5秒过去了),锁定屏幕并重新设置Count为0。
  4. 休眠500毫秒
  5. 重复步骤2-4

这是我的代码。在应用程序启动时调用"startLockHandler"方法。

 public void startLockHandler()
 {
     Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => lockHandler()), null);
 }
 public void lockHandler()
    {
        while (true)
        {
            if (myState.isSkeletonTracked == false) //if skeleton is no longer tracked 
            {
                if (myState.ActionAllowed == true) //if the page is not in transition
                {
                    lockCount++;
                    if (lockCount >= 10)
                    {
                        lockCount = 0;
                        myState.ActionAllowed = false;
                        //LOCKING MECHANISM INSERTED HERE. NEED TO MODIFY SOME WPF ELEMENTS
                        myState.ActionAllowed = true;
                    }
                }
            }
            else
            {
                lockCount = 0;
            }
            Console.WriteLine("lockHandler: THREAD SLEEP CALLED");
            Thread.Sleep ( 500 );
        }//end while
    }//end method lockHandler 

当我运行应用程序时,应用程序在启动后立即挂起。我认为发生的是线索。Sleep(500)指示主线程休眠(如果我错了请纠正我)。我的问题是如何指定要进入睡眠状态的线程?顺便说一句,我不是c#专家,也是线程的新手:(

谢谢你的关注,希望你能帮助我:)

线程调度程序在WPF中休眠

  1. Dispatcher.BeginInvoke()不创建新线程,它只是在主GUI线程上执行lockHandler()。传递ThreadStart委托在这里没有什么特别的意义。

  2. Thread.Sleep()将调用它的线程置于睡眠状态,这是您的情况下的主要GUI线程。要控制从一个头到另一个头的执行,您应该使用同步原语(ManualResetEvent, AutoResetEvent, Mutex, Semaphore等)。

  3. 你不应该直接从另一个线程访问/修改UI,你必须从二级线程(不是GUI线程)调用InvokeBeginInvoke Dispatcher方法,以确保所有与UI相关的代码都是从创建UI元素的线程执行的。

  4. 你真的不需要一个具有专用Dispatcher实例的二级线程。

最小修改,至少会使用一个单独的线程:

var thread = new Thread(lockHandler);
thread.Start();

记住,你还需要实现一种方法来停止你的二级线程,否则它可能会阻止你的应用程序关闭和从内存中卸载。一个快速(非常)肮脏的解决方案是将此线程标记为后台线程:thread.IsBackground = true .

从次线程修改UI的例子:

Application.Current.Dispatcher.BeginInvoke(new Action(
    () =>
    {
         // access UI elements here, for example
         myState.ActionAllowed = false;
    }));