【问题标题】:WCF Streaming - Limiting speedWCF 流 - 限制速度
【发布时间】:2012-05-26 19:53:48
【问题描述】:

这是我申请中的一个严重问题,几个月来没有找到任何好的解决方案。 我注意到 C# 管理 Stream 类在 WCF 中流式传输的方式,而不考虑我的配置。

首先,我有一个继承自 FileStream 的类,因此我可以随时查看从客户端读取了多少内容:

public class FileStreamWatching : FileStream
    {
        /// <summary>        
        /// how much was read until now        
        /// </summary>        
        public long _ReadUntilNow { get; private set; }
        public FileStreamWatching(string Path, FileMode FileMode, FileAccess FileAccess)
            : base(Path, FileMode, FileAccess)
        {
            this._ReadUntilNow = 0;
        }
        public override int Read(byte[] array, int offset, int count)
        {
            int ReturnV = base.Read(array, offset, count);
            //int ReturnV = base.Read(array, offset, count);
            if (ReturnV > 0)
            {
                _ReadUntilNow += ReturnV;
                Console.WriteLine("Arr Lenght: " + array.Length);
                Console.WriteLine("Read: " + ReturnV);
                Console.WriteLine("****************************");
            }
            return ReturnV;
        }
    }

其次,下面是我读取包含文件的客户端流的服务方法。 我的主要问题是 FileStreamWatching.Read 每次我从下面的这个方法召唤它时都不会启动,而是 FileStreamWatching.Read 每次我调用它 X 次都会启动一次.. 奇怪。

*稍后看看输出

    public void Get_File_From_Client(Stream MyStream)
    {
        using (FileStream fs = new FileStream(@"C:\Upload\" + "Chat.rar", FileMode.Create))
        {
            byte[] buffer = new byte[1000];
            int bytes = 0;
            while ((bytes = MyStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                fs.Write(buffer, 0, bytes);
                fs.Flush();
            }
        }
    }

这是每次激活 FileStreamWatching.Read 时客户端的输出:(记住缓冲区长度只有 1000!)

Arr 长度:256, 阅读:256


Arr 长度:4096, 阅读:4096


Arr 长度:65536, 阅读:65536


Arr 长度:65536, 阅读:65536


Arr 长度:65536, 阅读:65536


Arr 长度:65536, 阅读:65536


....直到文件传输完成。

问题:

  1. 我带到读取方法的缓冲区长度不是 256/4096/65536。是 1000。
  2. 每次我从服务调用 FileStreamWatching 类时,读取都不会启动。

我的目标:

  1. 控制每次读取我从客户端收到多少。

  2. 每次我从服务调用 FileStreamWatching.Read 时都会启动它。

我的客户端配置:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IJob" transferMode="Streamed"/>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8080/Request2" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IJob" contract="ServiceReference1.IJob"
                name="BasicHttpBinding_IJob" />
        </client>
    </system.serviceModel>
</configuration>

我的服务配置(这里没有配置文件):

        BasicHttpBinding BasicHttpBinding1 = new BasicHttpBinding();
        BasicHttpBinding1.TransferMode = TransferMode.Streamed;
        //
        BasicHttpBinding1.MaxReceivedMessageSize = int.MaxValue;
        BasicHttpBinding1.ReaderQuotas.MaxArrayLength = 1000;
        BasicHttpBinding1.ReaderQuotas.MaxBytesPerRead = 1000;
        BasicHttpBinding1.MaxBufferSize = 1000;
        //
        ServiceHost host = new ServiceHost(typeof(JobImplement), new Uri("http://localhost:8080"));
        //
        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
        behavior.HttpGetEnabled = true;
        //
        host.Description.Behaviors.Add(behavior);
        ServiceThrottlingBehavior throttle = new ServiceThrottlingBehavior();
        throttle.MaxConcurrentCalls = 1;
        host.Description.Behaviors.Add(throttle);
        //
        //
        host.AddServiceEndpoint(typeof(IJob), BasicHttpBinding1, "Request2");
        host.Open();

【问题讨论】:

  • MyStream.Read(buffer, 0, buffer.Length) - 每次调用后偏移量不应该增加吗?
  • @Tisho 应用程序可能会更改每次调用的偏移量。它是否会影响 Stav 在代码中此时提出的问题。

标签: c# wcf wcf-streaming


【解决方案1】:

回复:为什么是 256/4K/65535?

我看到这里有两种可能性:

  • 基础FileStream 正在做自己的内部缓冲。它可能在内部调用read(array,offset,length) 来填充其内部缓冲区,然后传回您要求的部分。内部调用最终是递归的,直到它读取了整个文件。然后您的覆盖将停止显示任何内容。
  • 还有其他stream.read() 签名未显示为被覆盖。如果任何代码路径最终调用了其他 read 方法之一,那么您的计数将被取消。

re:MyStream 每次都没有重新开始

MyStream 参数是否已处理?还是重新用于新流?您的代码仅在构造函数中“重新启动”,因此确保在您更改传入流时对象已被释放并重新构造。

您可以通过在到达 EOF 时也显示一些内容来测试递归 EOF 情况。

如果添加静态变量来计算应用程序对MyStream.Read 的调用和方法进入/退出,则可以测试意外递归。如果它们不匹配,则 FileStream 正在进行内部(意外递归)调用。

-杰西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2021-03-24
    相关资源
    最近更新 更多