Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF中的线程调度程序睡眠_C#_Wpf_Multithreading_Dispatcher - Fatal编程技术网

C# WPF中的线程调度程序睡眠

C# WPF中的线程调度程序睡眠,c#,wpf,multithreading,dispatcher,C#,Wpf,Multithreading,Dispatcher,我正在尝试创建一个Kinect+WPF应用程序。Kinect部分工作良好;现在我想创建一个方法来检查页面是否空闲(在特定时间内没有用户与程序交互)。如果空闲5秒钟,屏幕将被锁定。这是算法: 启动线程(我需要使用Dispatcher,因为线程需要修改WPF元素) 检查用户是否正在使用。如果不是,则将计数增加1 如果Count==9(这意味着已经过了5秒),请锁定屏幕并再次将Count设置为0 睡眠500毫秒 重复步骤2-4 这是我的密码。应用程序启动时调用方法“startLockHandler”

我正在尝试创建一个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
    delegate这一事实在这里没有什么特殊意义

  • Thread.Sleep()
    将调用它的线程置于睡眠状态,在您的示例中,这是主GUI线程。要控制一个和另一个的执行,您应该使用同步原语(
    ManualResetEvent
    AutoResetEvent
    Mutex
    信号量
    等)

  • 您不应该直接从另一个线程访问/修改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;
        }));
    

    在生产代码中休眠通常是一个坏主意(tm)。我想不出任何其他解决方案。为什么不使用
    计时器
    而不是
    线程。休眠
    ?如果我不使用Dispatcher,则会出现错误“调用线程无法访问此对象,因为其他线程拥有它”。线程无法修改WPF元素。你能给出一个你答案3的代码示例吗?我很难理解。我没有说你不需要使用
    调度程序
    ,你应该从另一个线程使用它,你没有创建它。添加了示例。