IEnumerable,流和WCF

时间:2018-03-18 00:30:22

标签: c# wcf stream ienumerable gzipstream

我正在编写一个向客户端返回大量数据的服务。理想情况下,我想返回实体的 IEnumerable ,因为我希望服务和客户端都具有懒惰的性能优势。我还希望能够压缩流以减少带宽。

我能够将 IEnumerable 序列化为流并利用 GZip 来压缩它。我还能够成功地反序列化流。但是,我的实现并没有达到我目标的懒惰部分。

我已经阅读了类似于我的问题的概念解决方案,但它们都涉及返回 IEnumerable 的字节。理想情况下,我希望客户端接收实体的 IEnumerable ,并且能够在反序列化时返回它。

[DataContract]
public class Entity
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Code { get; set; }
    [DataMember]
    public string Description { get; set; }
}

[Test]
public void TestSerialEnumGzip()
{
    var e = GetEnum();
    var s = SerializeToStreamGzip(e);
    Console.WriteLine($" TestSerialGzip stream size {s.Length}");
    var b = DeserializeFromStreamGzip<IEnumerable<Entity>>(s);
}

private IEnumerable<Entity> GetEnum()
{
    for (var x = 0; x < 10; ++x)
    {
        Console.WriteLine($"yielding {x}");
        yield return new Entity { Id = x, Code = x.ToString(), Description = x.ToString() };
    }
}

private Stream SerializeToStreamGzip<T>(T toSerialize)
{
    var s = new MemoryStream();
    using (var gz = new GZipStream(s, CompressionMode.Compress, true))
    {
        var ser = new DataContractSerializer(typeof(T));
        ser.WriteObject(gz, toSerialize);
    }
    s.Seek(0, SeekOrigin.Begin);
    return s;
}

private T DeserializeFromStreamGzip<T>(Stream stream)
{
    var ser = new DataContractSerializer(typeof(T));
    var gz = new GZipStream(stream, CompressionMode.Decompress);
    var result = (T)ser.ReadObject(gz);
    return result;
}

1 个答案:

答案 0 :(得分:1)

我认为你可能对 IEnumerable 感到有点困惑。但是,除此之外,你真的应该把你的研究重点放在 WCF Streaming

查看此博客Custom WCF Streaming及其相关的example。它基本上封装了您想要的所有内容,并使用BinaryFormatter

如果您想更进一步,可以使用协议缓冲区 Protobuf-net或添加自己的广告压缩。但是,我将这些细节留给您。

  

基本思想是:我们将有两个线程,一个线程将执行   复杂的数据库查询和另一个线程将数据库行流   客户。所以我们将改变数据库查询,使其返回   每次只有1000行。并修改WCF服务以流式传输这些   1000行到客户端。 WCF服务是将数据库行传输到   客户端,同时在不同的线程上,WCF服务将   再次运行数据库查询以获取下一个1000行。这样的方式   WCF服务完成将流行传输到客户端后,即可   下一组行可用于流式传输到客户端

enter image description here

  1. WCF客户端调用WCF服务
  2. WCF服务执行数据库查询
  3. 数据库将数据集返回给WCF服务
  4. WCF服务响应
  5. WCF服务执行的第二个数据库查询
  6. WCF流响应