我正在尝试创建Kinect + WPF应用程序。 Kinect部分工作正常;现在我想创建一个方法来检查页面是否空闲(没有用户在特定的时间内与程序交互)。如果它空闲5秒钟,屏幕将被锁定。这是算法:
这是我的代码。方法" 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#专家和线程新手:(
感谢您的关注,希望您可以帮助我:)。
答案 0 :(得分:2)
Dispatcher.BeginInvoke()
不创建新线程,它只是在主GUI线程上执行lockHandler()。你通过ThreadStart
委托的事实在这里没什么特别的。
Thread.Sleep()
将调用它的线程置于睡眠状态,这是您案例中的主要GUI线程。要控制另一个thead的执行,你应该使用同步原语(ManualResetEvent
,AutoResetEvent
,Mutex
,Semaphore
等。
您不应该直接从另一个线程访问/修改UI,您必须从辅助线程(而不是GUI线程)调用Invoke
或BeginInvoke
Dispatcher
方法,以确保所有与UI相关的代码都是从创建UI元素的线程执行的。
您实际上并不需要一个带有专用Dispatcher
实例的辅助线程。
最小修改,至少使用一个单独的线程:
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;
}));