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”属性正在通过本地绑定调用期间被序列化和反序列化!

有没有人使用过这种方法或知道是否有问题?

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");
}

这向我暗示了几种可能性之一:

  • 他们打算保留您通常在 WCF 中看到的复制语义,客户端和服务器查看不同的副本
  • 它根本行不通
  • 文档有误

鉴于这里的声明说:

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

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

然而!也可能是它打算切掉堆栈的某些部分(主要是 IO 堆栈),但是编写文档页面的人误解了,并错误地指出也省略了序列化。

于 2012-07-24T11:48:06.497 回答