2011-12-13 57 views
0

我的.net遠程處理服務器應用程序的遠程處理方法有時會在由於同步問題而被客戶端調用時掛起。這些方法執行一些數據庫讀/寫操作並將結果返回給客戶端。它不能正確處理數據庫鎖定,因此會出現懸掛問題。不幸的是,我們沒有使用數據庫的模塊代碼(用C++本機代碼實現),所以我必須找到解決方法。 我想如果服務器應用程序可以得到通知時,任何遠程處理方法掛起,服務器應用程序可以重新啓動自己。在我的情況下,重新啓動服務器應用程序是可以接受的,我已經找到了一種方法來做到這一點。那麼當遠程方法掛起時,有沒有什麼好方法可以讓服務器應用程序知道?如何檢測.net遠程處理方法是否掛在服務器應用程序端?

+0

,你可以在一個單獨的線程asynchonously執行方法......如果執行時間花費太多時間,你「知道」它掛起... – Yahia

+0

任何機會,你會停止使用遠程處理,並開始使用現代技術,如WCF –

回答

0

假設一個超時是不夠好,你不需要解決halting problem

public class TimeoutChecker 
{ 
    private static Dictionary<Thread, DateTime> hashTimeouts 
     = new Dictionary<Thread, DateTime>(); 
    static TimeoutChecker() 
    { 
     new Thread(CheckThread).Start(); 
    } 
    protected static void CheckThread() 
    { 
     while (true) 
     { 
      try 
      { 
       Thread.Sleep(500); 
       foreach (DateTime t in hashTimeouts.Values) 
       { 
        if (DateTime.Now.AddMilliseconds(10 * 1000) < t) 
        { 
         //Perform recovery logic. 
        } 
       } 
      } 
      catch (Exception) { } 
     } 
    } 
    public static void BeforeCall() 
    { 
     hashTimeouts.Add(Thread.CurrentThread, DateTime.Now); 
    } 
    public static void AfterCall() //be sure to execute in a finally... 
    { 
     hashTimeouts.Remove(Thread.CurrentThread); 
    } 
} 

這裏,BeforeCall和AfterCall將在本機調用外部的包裝,但遠程方法調用中。

當然,在調用本機代碼以避免死鎖之前使用同步可能是一個更好的主意。

0

您可以在Remoting連接上設置超時。當時間到了,但服務器的方法沒有返回時,Remoting會自動拋出RemotingException。

+0

如果服務器沒有返回(如果發生死鎖或甚至無限次睡眠),客戶端可能會收到RemotingException。那在服務器端呢?我不確定服務器應用程序也會得到RemotingException。 –

+0

對。來自客戶端的每個遠程調用都是在從內置的.NET線程池獲取的單獨線程上執行的。如果該線程發生死鎖或無限睡眠,它將永遠不會返回。您應該考慮重構服務器方法中的代碼。 @ebyrob對將調用同步到本機C++庫有一個很好的建議。 –

相關問題