2014-12-27 47 views
0

我有一個惱人的問題... 我只是想顯示一個對話框,但它總是呈現兩次......下面的代碼:.ShowDialog()出現了兩次

private void tmr_sysdt_Tick(object sender, EventArgs e) 
    { 
     lbl_time.Text = System.DateTime.Now.ToLongTimeString(); 
     lbl_date.Text = System.DateTime.Now.ToLongDateString(); 
     if (GetLastInputTime() > Program.timeout) 
     { 
      frm_lockscreen login= new frm_lockscreen(); 
      tmr_sysdt.Enabled = false; 
      if (login.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true; 
     } 
    } 

的。

問題很簡單 - 但對我而言無法解決 - 對話框顯示爲重複(第二個會在第一個時間到達)。

我不知道,所以任何想法可以理解的:)

謝謝你,如果你需要更多的詳細信息,請發表評論!

詩:對不起,壞工程


編輯:GetLastInputTime()

[DllImport("user32.dll")] 
    static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); 
    static uint GetLastInputTime() 
    { 
     uint idleTime = 0; 
     LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); 
     lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); 
     lastInputInfo.dwTime = 0; 

     uint envTicks = (uint)Environment.TickCount; 

     if (GetLastInputInfo(ref lastInputInfo)) 
     { 
      uint lastInputTick = lastInputInfo.dwTime; 

      idleTime = envTicks - lastInputTick; 
     } 

     return ((idleTime > 0) ? (idleTime/1000) : 0); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct LASTINPUTINFO 
    { 
     public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO)); 

     [MarshalAs(UnmanagedType.U4)] 
     public UInt32 cbSize; 
     [MarshalAs(UnmanagedType.U4)] 
     public UInt32 dwTime; 
    } 
+0

運行GetLastInputTime +創建畫面可能需要更長的時間超過1秒? – 2014-12-27 14:07:48

+0

不,我已經用5000ms嘗試過了...... :( – RAPTOR 2014-12-27 14:08:46

+1

不相關,但是你知道在第一行執行完日期後,在兩個單獨的行上調用System.DateTime.Now是有問題的嗎?那麼你的表單將會顯示一個接近24小時的時間這是一個不太可能,但仍然buggy – doublehelix 2014-12-27 14:15:00

回答

1

你可以試試這段代碼嗎?只是,以確保您的處理程序中的邏輯不同時叫了兩聲:

static bool busy = false; 
    private void tmr_sysdt_Tick(object sender, EventArgs e) 
    { 
     if (busy) 
     { 
      return; 
     } 
     busy = true; 
     try 
     { 
      lbl_time.Text = System.DateTime.Now.ToLongTimeString(); 
      lbl_date.Text = System.DateTime.Now.ToLongDateString(); 
      if (GetLastInputTime() > Program.timeout) 
      { 
       frm_lockscreen login = new frm_lockscreen(); 
       tmr_sysdt.Enabled = false; 
       if (login.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true; 
      } 
     } 
     finally 
     { 
      busy = false; 
     } 
    } 

您遇到的是,該代碼檢查用戶的最後一項活動,並顯示登錄框的問題,是在多次創建的表單中。
所以實際上,這些「主要表單」中的每一個都在檢查用戶活動並顯示登錄框。

通過將busy bool設置爲靜態,'main form'的每個實例都將此bool讀爲相同的值。因此,check + show登錄只能執行一次。

我建議將此代碼移動到您只創建一次的表單,並在應用程序的整個生命週期中保持打開狀態。 (如果你有這樣的一種形式)

+1

同意重要的是不要觸發兩次。但一個更簡單的方法來實現這一點是有tmr_sysdt .Enabled =事件處理程序開始處的false行和finally子句中的tmr_sysdt.Enabled = true。這樣可以消除忙碌的布爾a nd相關的代碼。 – doublehelix 2014-12-27 14:13:15

+0

它顯示了兩次:( – RAPTOR 2014-12-27 14:14:38

+0

我認爲doublehelix將是正確的,因爲如果我打破了第一個顯示對話框,然後只需按下F11按鈕,然後我只有一個對話框......但我無法理解爲什麼 – RAPTOR 2014-12-27 14:16:39

0

的原因是,你的外if條件是返回true兩次:

if (GetLastInputTime() > Program.timeout) 

要找到罪魁禍首,你必須檢查由GetLastInputTime()和Program.Timeout返回的值

+0

我無法調試此,因爲GetLastInputTime()計數不活動,當我按F5或F11它重置...但我認爲這是問題的關鍵... – RAPTOR 2014-12-27 14:21:05

1

你想重用你frm_lockscreen,防止再進入你的Tick事件

private frm_lockscreen _lockScreen; 

private frm_lockscreen LockScreen 
{ 
    get { return _lockScreen ?? (_lockScreen = new frm_lockscreen()); } 
} 

private void tmr_sysdt_Tick(object sender, EventArgs e) 
{ 
    // prevent reentry 
    if (!Monitor.TryEnter(tmr_sysdt)) return; 

    try { 
     lbl_time.Text = System.DateTime.Now.ToLongTimeString(); 
     lbl_date.Text = System.DateTime.Now.ToLongDateString(); 
     if (GetLastInputTime() > Program.timeout) 
     { 
      tmr_sysdt.Enabled = false; 
      if (LockScreen.ShowDialog(this) == DialogResult.OK) tmr_sysdt.Enabled = true; 
     } 
    } 
    finally { 
     Monitor.Exit(tmr_sysdt); 
    } 
} 
+0

'get {_lockScreen ?? (_lockScreen = new frm_lockscreen()); }' _Only賦值,調用,遞增,遞減,等待和新的對象表達式可以用作語句_ – RAPTOR 2014-12-27 14:52:45

+0

OFF:但是我喜歡這個'''''操作符,+1表示它! :) – RAPTOR 2014-12-27 14:55:12

+0

不是? '得到{return _lockScreen ?? (_lockScreen = new frm_lockscreen()); }' – RAPTOR 2014-12-27 14:56:38