11

私は WPF アプリケーションの問題で数日間苦労してきました。問題は、Web メソッド呼び出しの型を処理するために「オンザフライ」でシリアライザーを生成するクライアントに要約されるようです。そのメソッドが初めて呼び出されるとき (Web サービス自体は既に実行されています)、たとえば 8 秒かかり、その後の呼び出しにはたとえば 20 ミリ秒かかる場合があります。この遅延の間、クライアント WPF プロセスの CPU は v. high です。

XmlSerializer を使用する場合、svcutil を使用してこれらのシリアライザー アセンブリを事前に生成する方法があります。(私たちのように) 通常の WCF DataContractSerializer を使用している場合、このオプションは存在しないようです。

私が望むのは、すべてのデータ コントラクト (大量) のすべての型に対してこのアセンブリを事前に生成できるようにすることです。あるいは、このプロセスを、コード化してバイナリでデータを渡すことができるカスタム プロセスに置き換えることです (この Web サービス/クライアントの両端を所有しており、どちらも .NET 4) です。私は既に BinaryForamtter と GZip 圧縮を使用しており、これによりデータの転送が高速化されますが、常に XML に復元されてフレームワークによって逆シリアル化されるため、この問題は残ります。

何か案は?

4

3 に答える 3

8

protobuf-netなどのバイナリ ライブラリを使用できます。これは非常に高速です。タイプごとにコードを生成する必要があるため初期起動コストがかかる場合でも、 orよりもはるかに優れていDataContractSerializerBinaryFormatterます。数秒得て、全体的によりスムーズなエクスペリエンスが得られるはずです。WCF と簡単に統合できます。WCF は引き続きさまざまなコントラクトを検査して、正しい WSDL とさまざまなメタデータを生成することに注意してください。

既定の Web プロキシの決定など、WCF の起動を遅くする可能性があるものは他にもあります。使用しない場合は、バインディング構成に含まれてuseDefaultWebProxyいることを確認してください。false

それでも、最適化のために何をしても、WCF の起動は一般的に遅いことがわかります。個人的には、同様のシナリオ (私は両端を制御し、クライアントは WPF アプリケーションでした) での速度低下との戦いにうんざりしていたので、単純に WCF を捨てて、ServiceStack + protobuf-net を選びました。最初の呼び出しは 2 ~ 3 秒から 100 ミリ秒に短縮され、その後のすべての HTTP 呼び出しは本当に瞬時に行われます。全体的なユーザー エクスペリエンスが大幅に向上しました。私は ServiceStack とはまったく関係がないことに注意してください。これは単なる私の経験です。

于 2012-10-11T09:27:11.447 に答える
2

生成されたサービス参照を見て、DataContractSerializer が実際に使用されていることを確認しましたか? サービス参照の追加操作中のスキーマの不一致により、デフォルトの DataContractSerializer の代わりに XmlSerializer コードが生成され、XmlSerializer に特有のこの動作を引き起こしている可能性があります。この場合、ご指摘のとおり、シリアル化コードを事前に生成してコールド スタートアップを改善できます: http://msdn.microsoft.com/en-us/library/aa751883.aspx。ありがとう。

于 2012-10-12T18:06:41.247 に答える
0

WCFサービスをプリロードすることで、コールドスタート時間を改善できます...つまり、最初のリクエストがロードされるのを待たずに...事前にロードしてください。

ほんの少しのアイデア...シリアル化の分野で物事をスピードアップするのに「役立つかもしれない」。

サービスタイプのシリアル化アセンブリの事前生成に関しては、Project | Buildに「GenerateSerializationAssembly」というオプションがあります。「On」に切り替えると、ビルド時にアセンブリが生成されます。実行時に動的に。

このオプションが、XMLSerializerベースのシリアライザーまたはDataContractSerializersのシリアル化アセンブリの事前生成専用であるかどうかは明確ではありません。「オン」に切り替えて、違いが生じるかどうかを確認してみてください。

また、クライアントとサーバーのコードの早い段階でこれを実行して、DataContractシリアライザーを実行することもできます...つまり、クライアントまたはサーバーが要求を処理する前に...(役立つかどうかはわかりません) )。

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

保守性を高めるために、リフレクションを使用してシリアル化するタイプを見つけるルーチンを作成できます。たとえば、DataContract....またはその他のheuritistics....または事前定義されたテーブルでマークされたタイプを探します。

于 2012-10-11T10:00:42.230 に答える