线程调度程序在WPF中休眠

时间:2011-12-18 05:34:02

标签: c# wpf multithreading dispatcher

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

  1. 启动线程(我需要使用Dispatcher,因为线程需要修改WPF元素)
  2. 检查用户是否正在使用。如果没有,则将Count增加1。
  3. 如果Count == 9(表示已经过了5秒),请锁定屏幕并再次将Count设置为0。
  4. 睡眠500毫秒。
  5. 重复步骤2-4
  6. 这是我的代码。方法" 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 
    

    当我运行应用程序时,应用程序在启动后立即挂起。我认为发生的是Thread.Sleep(500)指示主线程睡眠(如果我错了,请纠正我)。我的问题是如何指定要放入哪个线程? 顺便说一下,我不是C#专家和线程新手:(

    感谢您的关注,希望您可以帮助我:)。

1 个答案:

答案 0 :(得分:2)

  1. Dispatcher.BeginInvoke()不创建新线程,它只是在主GUI线程上执行lockHandler()。你通过ThreadStart委托的事实在这里没什么特别的。

  2. Thread.Sleep()将调用它的线程置于睡眠状态,这是您案例中的主要GUI线程。要控制另一个thead的执行,你应该使用同步原语(ManualResetEventAutoResetEventMutexSemaphore等。

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

  4. 您实际上并不需要一个带有专用Dispatcher实例的辅助线程。

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

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

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

    <强>更新

    从辅助线程修改UI的示例:

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