2012-10-11 58 views
11

我一直在努力工作幾天,遇到了WPF應用程序的一個問題,我想知道是否有人遇到過這個問題,並且可以提供幫助嗎? 這個問題似乎歸結爲客戶端生成「即時」序列化程序來處理該Web方法調用中的類型。當第一次調用該方法時(Web服務本身已經運行),可能需要例如8秒,隨後的呼叫可能需要例如20毫秒。在此延遲期間,客戶端WPF進程上的CPU處於高位。從WPF使用WCF首次使用時速度很慢

使用XmlSerializer時,有一種使用svcutil預先生成這些序列化程序集的方法。當(像我們一樣)使用普通的WCF DataContractSerializer時,這個選項似乎不存在。

我希望能夠爲我的所有數據協定(很多)中的所有類型預先生成這個程序集,或者用一個自定義的代碼替換這個程序,我可以編寫和傳遞數據在二進制文件(我們擁有這個Web服務/客戶端的兩端,他們都是.NET 4)。我已經使用了BinaryForamtter和GZip壓縮功能,雖然這加速了數據的傳輸,但它總是會恢復到XML以被框架反序列化,因此這個問題依然存在。

任何想法?

回答

8

您可以使用二進制庫,例如protobuf-net,這是非常快的,即使有初始啓動成本,因爲必須爲每種類型生成代碼,它仍然是way better than DataContractSerializer or BinaryFormatter。您應該獲得幾秒鐘的時間,並獲得更平滑的體驗。它可以是easily integrated with WCF。請記住,WCF仍然會檢查您的各種合約以生成正確的WSDL和各種元數據。

還有其他一些可以減慢WCF啓動的事情,比如確定默認的Web代理。如果您沒有任何用處,請確保您的綁定配置中的useDefaultWebProxyfalse

儘管如此,你會發現WCF的啓動速度通常很慢,無論你如何優化它。就個人而言,在類似的情況下(我控制了兩端,客戶端是WPF應用程序),我厭倦了戰鬥緩慢,我只是放棄了WCF並去了ServiceStack + protobuf網。第一次呼叫從2-3秒變爲100ms,所有後續的HTTP呼叫都是瞬時的。整體用戶體驗大大改善。請注意,我與ServiceStack沒有任何關係,這只是我的經驗。

+0

感謝Julien,我已經得到了useDefaultWebProxy false。我期待使用protobuf-net,但是我無法理解它需要我用一個新的屬性重新裝飾我的所有數據類型 - 我希望不會。它在網站上說,如果你願意,v2可以「沒有屬性地使用」,但是所有的例子都使用屬性。這會提高第一次調用的啓動速度,即使在IIS中(這是真正的授權),也就是構建時預生成的protobuf-net串行器嗎? –

+0

@SimonEvans,只要你在每個'DataMember'上設置了'Order'屬性,你就應該沒問題。雖然我沒有使用它(我從一開始就使用protobuf)。 –

+0

朱利安,你的意思是我必須爲每個公共財產增加[ProtoMember(n)]?謝謝你的幫助 –

0

您可以通過預加載WCF服務來改善冷啓動時間......即,不要等待第一個請求導致它被加載...提前加載。

只是一些想法......這 「可能」 有助於加快在系列化地區的事情。

關於爲您的服務類型預先生成序列化程序集....在項目|構建中有一個名爲「生成序列化程序集」的選項....如果切換爲「開」,那麼它會生成程序集在運行時建立時間而不是動態的。

目前還不清楚此選項是否僅適用於基於XMLSerializer的序列化器或DataContractSerializers的序列化程序集的預生成。您可以嘗試將其切換爲「開啓」以查看它是否有所作爲。

您也可以嘗試在客戶端和服務器的代碼中儘早做到這一點,以便鍛鍊DataContract序列化程序......即,在客戶端或服務器不得不處理請求之前......(不知道它是否有幫助)。

DataContractSerializer ps = new DataContractSerializer(typeof(Person)); 
DataContractSerializer cs = new DataContractSerializer(typeof(Company)); 
etc... 

爲了使它更易於維護,您可以編寫一個例程,使用反射來查找您打算序列化的類型,例如,尋找標有DataContract ....或某些其他啓發式...或預定義表格的類型。

+1

感謝科林,我已經嘗試了以上所有內容,而這些都沒有任何區別。最後一個建議的問題是,我想處理的問題是客戶端啓動緩慢,因此,如果我爲序列化程序啓動,或者如果框架這樣做,它將不會影響,它將花費相同的時間。大多數冷啓動修復與服務器端相關,這不是問題。 「生成序列化程序集」選項僅適用於XmlSerializer,然後只有VS找到代理(我們有自己的代理)。 –

+0

這個鏈接可能會給你一些不同的策略的想法採取.... http://www.icodeteam.net/default/post/iCodeTeam/35/Object-Serialization-in-NET-Available-serialization-libraries/ –

2

您是否確認通過查看DataContractSerializer確實正在使用的生成服務引用?由於在添加服務引用操作期間某些模式不匹配,可能會導致生成XmlSerializer代碼,而不是導致XmlSerializer典型的這種行爲的默認DataContractSerializer。在這種情況下,正如您所指出的 - 您可以預先生成序列化代碼來改善冷啓動:http://msdn.microsoft.com/en-us/library/aa751883.aspx。 謝謝。

相關問題