2011-12-18 43 views
1

我正在嘗試創建一個Kinect + WPF應用程序。 Kinect部分工作正常;現在我想創建一個方法來檢查頁面是否空閒(沒有用戶正在與程序進行特定的時間交互)。如果它閒置5秒鐘,屏幕將被鎖定。這是算法:線程調度程序在WPF中睡眠

  1. 啓動線程(我需要使用調度程序作爲線程需要修改WPF元素),如果用戶使用的是
  2. 檢查。如果不是,則通過1
  3. 增加計數如果Count == 9(這意味着已5秒過去了),鎖定屏幕,並設置再次計數爲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 

當我運行應用程序時,應用程序在啓動後立即掛起。我認爲發生的是Thread.Sleep(500)指示主線程睡眠(如果我錯了,請糾正我)。我的問題是如何指定哪個線程進入睡眠狀態? 順便說一句,我不是在C#中的專家,並在線程:(

感謝您的關注新手,希望你能幫助我:)

+0

它通常是一個壞主意(TM),以在生產代碼 – 2011-12-18 05:58:53

+0

睡覺我不能認爲任何其它溶液.. – user1055010 2011-12-18 06:30:51

+0

爲什麼不使用'Timer'而不是'Thread.Sleep'? – ebb 2011-12-18 09:23:22

回答

2
  1. Dispatcher.BeginInvoke()不會產生新的線程,它只是在主GUI線程上執行lockHandler()。你通過ThreadStart委託事實意味着這裏沒什麼特別的。

  2. Thread.Sleep()把睡覺調用它的線程,也就是你的情況主界面線程。要從另一個你應該使用同步原語(ManualResetEventAutoResetEventMutexSemaphore等)控制一個THEAD的執行。

  3. 你不應該訪問/直接從另一個線程修改UI,你必須調用從輔助線程(非GUI線程)InvokeBeginInvokeDispatcher方法,以確保所有UI相關的代碼是從創建UI元素的線程中執行。

  4. 你並不真的需要一個輔助線程具有專用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; 
    })); 
+0

如果我不使用Dispatcher,那麼錯誤「調用線程不能訪問此對象,因爲不同的線程擁有它。」將出現,因爲線程無法修改WPF元素。你能給出你答案3的代碼示例嗎?我很難理解。 – user1055010 2011-12-18 08:20:53

+0

我沒有說你不需要使用'Dispatcher',你應該從另一個線程使用它,而不是你創建的。添加示例。 – max 2011-12-18 08:23:17