2009-08-14 55 views
4

我有用C#編寫的Windows服務。它運作良好,表現良好。我已將WCF服務添加到Windows服務,以使客戶端應用程序能夠連接到Windows服務並從Windows服務獲取有狀態的信息。如何在可以訪問Windows服務中的有狀態信息的Windows服務中設置WCF ServiceHost

我配置WCF服務是一個單,使得相同的服務實例是用來處理來自所有客戶端的所有請求如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

所有客戶端能夠在WCF服務中連接並訪問相同的有狀態信息。但是,我遇到了以下特殊行爲。

修訂:
我實例WCF 合同我的Windows服務中的服務。實例化時分配的任何有狀態信息都可用於連接到該服務的所有客戶端。

但是,任何有狀態信息直接從Windows服務(不是客戶端)添加到服務合同實例中,對於連接到該服務的客戶端不可見。就好像服務合同有兩個實例:一個用於Windows服務,另一個用於連接到WCF服務的客戶端。

什麼是建議(最好)的方式來實例化WCF服務,並讓它能夠訪問Windows服務中可用的有狀態信息?

回答

2

我建議通過在一個靜態成員中保持你的狀態來做一個結束運行,以便WCF是否爲每個調用創建一個新的實例或重用它。這解決了問題並簡化了代碼。

2

爲什麼WCF服務必須有狀態信息?難道不能將它存儲在數據庫中並在需要時進行訪問?

WCF確實允許Singleton實例提供服務 - 但通常不鼓勵使用它,除非您絕對必須這樣做。通常情況下,如果你可以將狀態信息存儲在一個數據庫表,並讓客戶端使用正常的每個調用WCF服務來訪問它。

UPDATE:
OK,另一個想法:你永遠只是要擁有一個ServiceHost的反正。如果您選擇「per-call」實例模式(按照所有領先專家的建議),ServiceHost將分配一個工作線程線程池,然後該線程池將爲傳入請求提供服務。

爲什麼WCF服務需要是單身人士?你不能使用「per-call」並且仍然使用NT服務中的有狀態信息嗎?

一個請求進來,你的服務對象(服務類,實現服務接口)的一個實例被創建。你現在如何訪問NT服務中的有狀態信息?難道你不能從新創建的服務實例那裏做到 - 當你真的需要它時?

如果你有有狀態的信息被保存在NT服務中,你需要確保任何併發訪問都將得到正確處理 - 這與你的WCF服務類是否是單例完全無關。

更新2:
使用「OperationContext.Current.Host」,你可以訪問託管服務方法內給定的服務實例正在執行ServiceHost的 - 不知道你是否可以訪問實際NT服務實例。但是,如果您創建自己的自定義ServiceHost後代,該後代具有附加屬性「ListOfClients」,那麼您應該可以隨時從運行的任何服務實例訪問該列表。

提個醒:,因爲有可能在任何給定時間處理的任何數量的服務請求,閱讀列表必須是線程安全的,並更新從Windows NT服務列表是更「危險」和需要考慮這些併發問題!如果您需要更新列表,請鎖定列表 - 否則,您將得到不可預知的結果。

馬克

+0

我並不真的需要WCF服務是有狀態的。我有Windows服務中的有狀態信息。我希望WCF服務能夠向請求它的客戶提供這些信息。我該如何解決這個問題? – Elan 2009-08-14 14:03:08

+0

當然,我可以通過將信息存儲到數據庫來解決這個問題。當信息已經在Windows服務中可用時,特別是當WCF服務託管在Windows服務的上下文中時,這似乎是不必要的開銷。看來我現在不必再另外存儲它並從數據庫中檢索它,以便客戶端訪問它。理想情況下,我希望WCF服務能夠訪問Windows服務中的有狀態數據。 – Elan 2009-08-14 14:20:53

+0

要回答你的問題,我最初開始了分配給列表中的WCF服務宿主實例的引用,但現在會得到這種方法走,因爲它不從需要一個Singleton手邊的工作。 – Elan 2009-08-14 15:08:10

1

設置InstanceContextMode.Single會導致ServiceHost的構建你的服務的一個實例,並利用它來進行所有呼叫。但是這聽起來像你想自己構造實例,並且使用對某些共享狀態的引用來填充它。如果是這樣,這就是所謂的「著名實例」模式,可以通過將實例到的ServiceHost constructory,像這樣來完成:

var svc = new MyServiceClass(state); 
var host = new ServiceHost(svc, new Uri(..), ...); 
... 

的ServiceHost將使用您傳遞所有電話的實例。

使用單實例模式時(無論對象是「衆所周知的」還是由ServiceHost構造的),一個重要的考慮因素是線程。默認情況下,WCF將只允許一個線程同時執行每個服務實例。因此,在PerCall實例模式下,由於您將有多個服務實例,因此您可以支持多個併發線程,這些線程將在正常情況下提高吞吐量。但是在單實例模式下,你只有一個服務實例,所以你一次只能運行一個線程。它取決於服務,但是將併發模式切換爲Multiple,這將允許多個併發線程進入您的服務實例,但要求您的服務實現是線程安全的。

一些很好的文檔在這裏:http://msdn.microsoft.com/en-us/library/ms731193.aspx

相關問題