2016-09-28 70 views
-2

我有一個具有兩個獨立GUI線程的應用程序,並且主窗體在每個線程上運行。 (這是爲了允許同時在不同屏幕上的獨立用戶)在應用程序啓動時啓動計時器間歇性死鎖

這些窗口中的每一個窗口都有一個InactivityTimer組件,它用於在用戶在一段時間內不活動後重新回到主頁。

主要功能的相關部分:

static void Main() 
    { 
     MainWindow form1 = new MainWindow(true); 

     //check that we have a second screen 
     if (Screen.AllScreens.Length > 1) 
     { //Setup the second screen on its own thread and bind events between the two 
      System.Threading.Thread thread = new System.Threading.Thread(() => 
      { 
       MainWindow form2 = new MainWindow(false); 
       form2.FormClosed += (o, e) => 
       { 
        form1.Invoke((MethodInvoker)delegate 
        { 
         form1.Close();//close form1 when form2 closes. we dont need vice-versa because form2 is on a background thread. 
        }); 
       }; 

       /* Logic that binds events between the two forms*/ 

       Application.Run(form2); 
      }) 
      { IsBackground = true }; 
      thread.Start(); 
     } 
     Application.Run(form1); 
    } 

的靜止定時器:

public partial class InactivityTimer : System.Windows.Forms.Timer, IMessageFilter 
{ 
    public InactivityTimer() 
    { 
     Initialise(); 
    } 

    public InactivityTimer(IContainer container) 
    { 
     Initialise(); 
     container.Add(this); 
    } 

    private void Initialise() 
    { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
    }    

    public void ResetTimer() 
    { 
     Stop(); 
     Start(); 
    } 

    public bool PreFilterMessage(ref Message m) 
    { 
     bool watching = /*logic that determines whether this is a message we are watching for (mainly mouse actions)*/; 
     if (watching) 
     { 
      ResetTimer(); 
     } 
     return false;//do not stop the event being dispatched 
    } 
} 

當我啓動應用程序,其中一個畫面總是先於另一個顯示出來,這並不令人意外。但有時(並非總是),當我在該屏幕與其他屏幕出現之前進行交互時,應用程序停止,就像死鎖一樣。第二個屏幕從不顯示,第一個屏幕停止響應輸入。

如果我在調試模式下發生這種情況時'斷線全部',則應用程序始終停留在InactivityTimer的ResetTimer()中的Start();上。

我曾經見過類似的行爲之前,我認爲這是因爲它有時會在它的父控件的句柄被創建之前啓動,而且如果IsHandleCreated爲false,則不會嘗試啓動計時器。
但是:
a)我甚至不知道這不僅僅是固定它的時間的改變;
b)在這種情況下,我非常確定,自窗口顯示以來,父句柄已經創建;
c)同樣的修復方法沒有在這裏工作。

我一直在挖掘這一段時間,並獲得無處不在。更糟的是,我似乎無法在削減的應用程序中複製這個問題。但我無法想象任何會阻礙計時器在停止工作後自動啓動的計時器。

如果有人可以請弄清楚發生了什麼事情和/或找出它的修復程序這將是驚人的。

+0

您的應用程序中是否存在您未在此顯示的任何同步機制,例如鎖或信號燈? –

+0

我在不同的地方使用了'lock(/ * lock object * /){}'塊,但是這些都是小部分,它們做的並不多,在應用程序的完全不相關的部分使用了不同的鎖對象。在最糟糕的情況下,我可能會遇到少量爭用,但沒有死鎖。 – fweaks

+0

這些是唯一會導致死鎖的事情。如果我們有機會幫助你解決問題,你需要向我們展示所有相關的代碼。 –

回答

0

我只是今天才知道發生了什麼,因爲調試器突然停在了一個完全不同的地方。

rory.ap在評論中是正確的,只有像鎖等事情會導致這樣的僵局。然而,當我查看我的代碼時,它從來沒有點擊過Invoke就像這樣的構造(關於UI線程),所以我沒有注意到這些。

但是,今天我的注意力被吸引到它,低看,我有一個lockInvoke,這是造成死鎖。

相關問題