2010-09-23 17 views
0

我們有許多類作爲singlecalls發佈在遠程處理通道中。該應用程序駐留在Windows服務中。它們在下列情況下使用:遠程處理通道調用Dispose方法兩次,同時從客戶端處置SingleCall對象

  1. 從使用CrossAppDomain遠程通道
  2. 通過網絡從遠程客戶端使用TCP信道
相同的應用程序域
  • 從另一個應用程序域

    由於在這三種情況下使用了這些類中的一些,我們有一些通用代碼可以與它們進行操作,例如:

    using(IRemoteObject remoteObject= (IRemoteObject) 
         RemotingHelper.GetObject(typeof(IRemoteObject))) 
    { 
        remoteObject.DoStuff(); 
    } 
    

    RemotingHelper已經知道如何根據場景創建對象。這是對Ingo Rammer的一個修改。

    所有遠程對象接口都從IDisposable繼承,並且所有遠程對象都繼承自MarshalByRefObject。

    因此,在前兩種情況下使用此代碼的情況下,代碼的行爲是正確的,但通過實際遠程使用時,遠程對象會創建兩次並處理兩次。

    這是因爲Dispose()方法調用,一個由使用言言,被管理作爲一種新的遠程調用,但遠程infraestructure已經調用該對象的Dispose自動,因爲這是怎麼了表現爲SingleCall對象:每次調用都會創建一個新實例並自動處理它。

    是否有任何配置值來避免這些重複(冗餘)調用?


    編輯:我已經知道爲什麼會發生這種情況。對於遠程SingleCall IDisposable對象,遠程處理通道在Method返回後自動調用Dispose,第二個調用由客戶端生成的代理完成,導致在服務器端實例化新對象,僅用於調用Dispose方法。

    這第二個電話是我想避免的,因爲它是不需要的。

  • +0

    爲什麼你需要在客戶端在所有處置?看起來,你可以從客戶端代碼中刪除(...)。 – VladV 2010-10-10 20:26:29

    +0

    我們不需要,我們在某些情況下這樣做,但我們有在案件2和3使用的幫手一些公共庫,我們希望避免編寫不同的助手。 – jmservera 2010-10-11 07:30:48

    回答

    1

    想更多地瞭解這一點,我傾向於認爲這是正確的行爲。據我所知,SingleCall,每次你調用對象的方法,服務器創建一個新的對象。所以有意義的是多個對象被創建和處置。即,此代碼:

    IRemoteObject remoteObject= (IRemoteObject) 
         RemotingHelper.GetObject(typeof(IRemoteObject)); 
    

    爲客戶端上的對象創建代理。如果我沒有記錯,則不會與服務器聯繫。

    現在,當你執行:

    remoteObject.DoStuff();

    遠程調用。服務器創建一個對象,執行該方法,返回值(如果有)以及處理該對象。

    然後,當您的通話Dispose(或由using聲明確實生成的代碼),則服務器將再次:創建一個對象,調用Dispose方法,並銷燬對象。

    這是SingleCall的工作方式:「當您將對象配置爲SingleCall對象時,系統會爲每個客戶端方法調用創建一個新對象。」 http://msdn.microsoft.com/en-us/library/aa719487(v=VS.71).aspx

    爲什麼不發生在你的方案1和方案2是有點混亂,雖然。

    舊響應:

    我不知道任何配置參數,以防止這種行爲。但是,如果實施Dispose方法as recommended,你應該有一個標誌,上面寫着對象是否已被釋放。所以多次撥打Dispose不應該是一個問題。

    +0

    這是一個問題,因爲它是一個遠程對象,所以遠程調用完成了。我要的是避免了線材在這種情況下,調用Dispose以兩種不同的情況下,這些額外的遠程調用,第一次是部署的對象,那麼一個新的實例調用的Dispose方法,因爲創建的遠程通道客戶端確實通過代理調用了該方法。 – jmservera 2010-09-23 20:13:12

    +0

    是的,我知道這是SingleCall工作的方式。在方案1和方案2它不會發生,因爲1,我們使用直接實例化(不涉及遠程)和2,我們使用跨AppDomain的(AppDomain.CreateInstanceFromAndUnwrap),它使用遠程處理,但你必須調用Dispose自己。在第三種情況下,遠程處理通道在方法調用返回時自動調用dispose。我想避免客戶端的代理調用遠程對象進行處理,因爲這是不需要的調用。它不會破壞任何東西,它只是過分的。 – jmservera 2010-09-23 21:34:03

    +0

    所以你想要的是客戶端代理對象說:「他在調用Dispose,但我知道這沒有必要,所以我只是不叫它。」我非常認真地懷疑有任何一種配置選項來指定這種行爲。 – 2010-09-23 21:57:30

    相關問題