为什么在WCF中使用LocalChannel时执行序列化?

Gho*_*eza 5 .net c# wcf wcf-binding

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

运行此代码表示在通过localbinding调用期间,'ProductDTO'类的'Price'属性正在被序列化和反序列化!

有没有人以前使用过这种方法或者知道是不是有问题?

Mar*_*ell 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");
}
Run Code Online (Sandbox Code Playgroud)

这向我提出了几种可能性之一:

  • 他们打算保留您通常在WCF中看到的复制语义,客户端和服务器查看不同的副本
  • 它根本不起作用
  • 文件是错的

鉴于此处的陈述说:

这对于客户端和服务在同一应用程序域中运行并且必须避免典型WCF通道堆栈(消息的序列化和反序列化)的开销的情况非常有用.

我宁愿怀疑中间的那个,即编写样本的人认为它正在工作,而没有实际检查序列化是否正在发生.

然而!它也可能是为了削减堆栈的某些部分(主要是IO堆栈),但是编写文档页面的人误解了,并错误地说明了序列化也被省略了.