2011-10-10 73 views
0

我正在開發一個WCF應用程序,它不遵循真正的SOA的想法世界,因爲它會有一些基本的調用。COM的看門狗線程

1)啓動過程 2)檢查進程仍在運行 3)獲取結果

這一切都是好的,但在執行順序從「啓動過程」回到我正在我的代碼使用

oThread = new Thread(new ThreadStart(wbrt.Calculate));

問題一個單獨的線程是已經公知的(雖然很少)的COM呼叫霸佔和坐在50〜100%的CPU和消耗大量內存。我無能爲力來阻止這一點。

我想要做的是有一個看門狗線程,如果在一段時間後仍然運行(比如說5分鐘),它將終止COM調用。

這裏有最佳做法嗎?我一直在閱讀以下博客:

http://weblogs.asp.net/israelio/archive/2004/06/19/159985.aspx

中,他利用「的AutoResetEvent」和「的WaitOne」這裏的問題是WaitOne的阻止,所以我得有一個線程中的一個線程。

我可以在這裏使用簡單的線程計時器嗎?我看到即使線程已關閉(即完成正常),計時器仍會執行,如果我使用標誌或某物來停止使用現在已死的對象,那麼該計時器會執行嗎?

另外我正在使用Activator.CreateInstance創建我的COM對象我嘗試中止線程,但它並沒有終止COM對象,因爲我讀了Abort是壞的。

我的解決方案是獲取COM實例的PID,並簡單地殺死,假設如果超時已經與外線打交道已經離開了窗口。

任何想法都很好!

+0

您將不得不在本身的進程中託管此COM對象,以便有機會從中止恢復。 –

+0

嗨它實例化COM的調用是在它自己的線程中,然後它啓動一個調用註冊並在其自己的進程中運行的ole服務器。 –

+1

如果通話完全被佔用資源和內存,那麼在不知道內部消息的情況下啓動它的方式是終止線程。然而,這個想法實在太瘋狂了,因爲這並不能有效保證手術的準確性(同步對象可能處於鎖定狀態,其他線程正在運行等),所以你最好把呼叫放到單獨的進程上上面Hans提出的建議。在這種情況下,終止進程將強制清理資源,並且您的父應用程序將優雅地脫離鎖定,而使用HRESULT而不是未釋放的鎖定。 –

回答

0

執行此操作的最簡單方法是使用超時值調用WaitAny()的一個ManualResetEvent。

ManualResetEvent _evtActor = new ManualResetEvent(); 

public void Start() 
{ 
    this._evtActor.Reset(); 

    ThreadPool.QueueUserWorkItem(new WaitCallback(DoStuff)); 

    int result = ManualResetEvent.WaitAny(
        new WaitHandle[] { this._evtActor }, 
        30 * 1000); // Wait 30sec 

    if (result == ManualResetEvent.WaitTimeout) 
    { 
     Console.WriteLine("Timeout occurred!"); 
    } 
    else 
    { 
     Console.WriteLine("Done!"); 
    } 
} 

public void DoStuff() 
{ 
    Console.WriteLine("Doing stuff."); 
    Thread.Sleep(45 * 1000); // sleep for 45sec; 
    this._evtActor.Set(); 
}