2010-03-26 35 views
3

我有一個Windows窗體應用程序,它本身啓動不同的線程來做不同種類的工作。偶爾,所有線程(包括UI線程)都會凍結,並且我的應用程序變得無法響應。我已經決定它可能是一個垃圾收集器相關的問題,因爲GC將暫時凍結所有管理線程。要驗證勉強線程都將凍結,我旋轉起來的非託管一個寫一個「心跳」文件與時間戳每一秒,並且不影響(即它仍然運行):如何模擬此應用程序掛起方案?

public delegate void ThreadProc(); 

[DllImport("UnmanagedTest.dll", EntryPoint = "MyUnmanagedFunction")] 
public static extern void MyUnmanagedFunction(); 

[DllImport("kernel32")] 
public static extern IntPtr CreateThread(
    IntPtr lpThreadAttributes, 
    uint dwStackSize, 
    IntPtr lpStartAddress, 
    IntPtr lpParameter, 
    uint dwCreationFlags, 
    out uint dwThreadId);  

uint threadId; 
ThreadProc proc = new ThreadProc(MyUnmanagedFunction); 
IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(proc); 
IntPtr threadHandle = CreateThread(IntPtr.Zero, 0, functionPointer, IntPtr.Zero, 0, out threadId); 

我的問題是:我怎樣才能模擬這種情況,所有託管線程都掛起,但非託管線程繼續旋轉?

我的第一個刺

private void button1_Click(object sender, EventArgs e) { 
    Thread t = new Thread(new ThreadStart(delegate { 
     new Hanger(); 
     GC.Collect(2, GCCollectionMode.Forced); 
    })); 
    t.Start(); 
} 
class Hanger{ 
    private int[] m_Integers = new int[10000000]; 
    public Hanger() { } 
    ~Hanger() { Console.WriteLine("About to hang..."); 

    //This doesn't reproduce the desired behavior 
    //while (true) ; 

    //Neither does this 
    //Thread.Sleep(System.Threading.Timeout.Infinite); 
    } 
} 

在此先感謝!

+0

通過冷凍你是指永久無響應(掛起)或僅僅是一個無反應的時期? 多少個線程和什麼樣的鎖定和/或同步機制是您使用? – 2010-03-26 19:59:58

+1

我想知道你是否有僵局。爲了模擬這一點,也許你可以嘗試在一個關鍵部分放一個無限循環(或者只是一個長時間的睡眠),從一個線程(也許是非託管的線程)輸入它,然後嘗試從所有其他線程輸入它,導致它們塊? – 2010-03-26 20:00:19

回答

1

終結器與「正常」線程執行同時執行。我們通常說GC會運行終結器,但更確切的說,GC會檢測哪些實例應該運行終結器,並將它們存儲在專用隊列中。 (隱藏)線程從隊列中提取實例並運行終結器。這種不同步是必要的,例如,因爲終結器可能自己分配內存並可能觸發GC。還有其他good reasons爲什麼終結者必然是異步的。

底線是,您不能在~Hanger()之間改變VM在GC暫停期間所做的操作,因爲那時實際運行~Hanger()的線程也會暫停。

0

我意識到這並不能回答你的問題,但我懷疑你的代碼中有一個死鎖,而不是一個奇怪的GC問題。

我建議檢查你的代碼的死鎖,尤其是間接的情況下,如從後臺線程進行UI更新時調用Control.Invoke。確保在調用Invoke時沒有鎖 - 這可能會導致意外的死鎖(就像預計會發生任何死鎖:))

0

支持Marek的回答,這看起來很像您正在使用的併發模型的設計問題。作爲設計問題,這是通過測試無法有效解決的問題。

我的建議是仔細考慮您正在使用的併發模型,並相應地更正設計。首先尋找僵局的必要條件,例如:

  1. 你有什麼共同排除?
  2. 您的流程(已使用某些資源)需要哪些其他資源?
  3. 哪些資源需要顯式釋放是使用它們的過程?

考慮到這些因素,如果你有循環資源分配結構,你正在尋找可能的死鎖情況。