线程调度程序在WPF中休眠
本文关键字:休眠 WPF 调度程序 线程 | 更新日期: 2023-09-27 18:18:05
我正在尝试创建一个Kinect + WPF应用程序。Kinect部分运行良好;现在我想创建一个方法来检查页面是否空闲(在特定的时间内没有用户与程序交互)。如果空闲时间超过5秒,屏幕将被锁定。算法如下:
- 启动线程(我需要使用Dispatcher作为线程需要修改WPF元素)
- 检查用户是否正在使用。如果没有,则增加1。
- 如果Count == 9(这意味着已经5秒过去了),锁定屏幕并重新设置Count为0。
- 休眠500毫秒
- 重复步骤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#专家,也是线程的新手:(
谢谢你的关注,希望你能帮助我:)
-
Dispatcher.BeginInvoke()
不创建新线程,它只是在主GUI线程上执行lockHandler()。传递ThreadStart
委托在这里没有什么特别的意义。 -
Thread.Sleep()
将调用它的线程置于睡眠状态,这是您的情况下的主要GUI线程。要控制从一个头到另一个头的执行,您应该使用同步原语(ManualResetEvent
,AutoResetEvent
,Mutex
,Semaphore
等)。 -
你不应该直接从另一个线程访问/修改UI,你必须从二级线程(不是GUI线程)调用
Invoke
或BeginInvoke
Dispatcher
方法,以确保所有与UI相关的代码都是从创建UI元素的线程执行的。 -
你真的不需要一个具有专用
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;
}));