5

Microsoft が提供するLocalChannelという名前の WCF サンプルがあり、同じ ApplicationDomain でサービスを呼び出すときに、カスタム バインディングを実装して不要なオーバーヘッドを回避する方法を示しています。サンプルの説明には、次のように記載されています。

これは、クライアントとサービスが同じアプリケーション ドメインで実行されており、一般的な WCF チャネル スタック (メッセージのシリアル化と逆シリアル化) のオーバーヘッドを回避する必要があるシナリオで役立ちます。

私は自分のプロジェクトでこのコードを使用しましたが、主張にもかかわらず、サービスが呼び出されるときにシリアル化が行われるようです。

より明確にするために、データ コントラクトを使用するようにコードを次のように変更しました。これにより、シリアル化が実行されているかどうかを簡単に判断できます。

# region Service Contract

[ServiceContract]
public interface IGetPrice
{
    [OperationContract]
    ProductDTO GetPriceForProduct(int productCode);
}


[DataContract]
public class ProductDTO
{
    private string _price;

    public ProductDTO(string price)
    {
        _price = price;
    }

    #region Overrides of Object

    public override string ToString()
    {
        return string.Format("Price = '{0}'", _price);
    }

    #endregion

    [DataMember]
    public string Price
    {
        get { return _price; }
        set { _price = value; }
    }
}

public class GetPrice : IGetPrice
{
    #region IGetPrice Members

    public ProductDTO GetPriceForProduct(int productId)
    {
        return new ProductDTO((String.Format("The price of product Id {0} is ${1}.",
                                             productId, new Random().Next(50, 100))));
    }

    #endregion
}

# endregion



internal class Program
{
    private static void Main(string[] args)
    {
        var baseAddress = "net.local://localhost:8080/GetPriceService";

        // Start the service host
        var host = new ServiceHost(typeof (GetPrice), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof (IGetPrice), new LocalBinding(), "");
        host.Open();
        Console.WriteLine("In-process service is now running...\n");

        // Start the client
        var channelFactory
            = new ChannelFactory<IGetPrice>(new LocalBinding(), baseAddress);
        var proxy = channelFactory.CreateChannel();

        // Calling in-process service
        var priceForProduct = proxy.GetPriceForProduct(101);
        Console.WriteLine("Calling in-process service to get the price of product Id {0}: \n\t {1}"
                          , 101, priceForProduct);
        Console.WriteLine("Calling in-process service to get the price of product Id {0}: \n\t {1}"
                          , 202, proxy.GetPriceForProduct(202));
        Console.WriteLine("Calling in-process service to get the price of product Id {0}: \n\t {1}"
                          , 303, proxy.GetPriceForProduct(303));

        Console.WriteLine("\nPress <ENTER> to terminate...");
        Console.ReadLine();
    }
}

このコードを実行すると、「ProductDTO」クラスの「Price」プロパティが、localbinding を介した呼び出し中にシリアル化および逆シリアル化されていることが示されます。

誰かがこの方法を以前に使用したことがありますか、または何かが間違っているかどうかを知っていますか?

4

1 に答える 1

6

コールバックを追加することで、シリアライゼーション/デシリアライゼーションが確実に行われていることを確認できます。

[OnSerializing]
internal void OnSerializing(StreamingContext context) {
    Console.WriteLine("OnSerializing");
}
[OnSerialized]
internal void OnSerialized(StreamingContext context) {
    Console.WriteLine("OnSerialized");
}
[OnDeserializing]
internal void OnDeserializing(StreamingContext context) {
    Console.WriteLine("OnDeserializing");
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext context) {
    Console.WriteLine("OnDeserialized");
}

これは、いくつかの可能性のうちの1つを示唆しています。

  • クライアントとサーバーが異なるコピーを見て、WCF で通常見られるコピー セマンティックを保持することを意図しています。
  • それは単に機能しません
  • ドキュメントが間違っている

ここでのステ​​ートメントが言うことを考えると:

これは、クライアントとサービスが同じアプリケーション ドメインで実行されており、一般的な WCF チャネル スタック (メッセージのシリアル化と逆シリアル化) のオーバーヘッドを回避する必要があるシナリオで役立ちます。

私はどちらかといえば中間のものを疑っています。つまり、サンプルを書いた人は誰でも、シリアル化が行われているかどうかを実際にチェックせずに、それが機能していると想定していました。

でも!スタックの一部(主に IO スタック)を切り取ることを意図していた可能性もありますが、ドキュメンテーション ページを書いた人は誤解し、シリアライゼーションも省略されていると誤って述べています。

于 2012-07-24T11:48:06.497 に答える