2012-05-26 44 views
7

这是一个严重的问题,在我的应用程序几个月没有找到任何好的解决方案。 我注意到C#管理Stream类在WCF中流式传输的方式,而不考虑我的配置。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启动时间为客户端的输出:(Remmber缓冲区lenght仅1000!)

编曲长度:256, 阅读:256


编曲长度:4096, 阅读:4096


编曲长度:65536, 阅读:65536


编曲长度:65536, 阅读:65536


编曲长度:65536, 阅读:65536


编曲长度:65536, 阅读:65536


....直到文件transfare完成。

问题:

  1. 我带到read方法心不是256/4096/65536缓冲区的Lenght。它是1000.
  2. 从服务中调用FileStreamWatching类的Read不会启动。

我的目标:

  1. Controling上我从客户的每次读多少reacive。

  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(); 
+0

MyStream.Read(缓冲,0,buffer.Length) - 不应该每次之后的偏移量增量打电话? – Tisho

+0

@Tisho应用程序可能会改变每次调用的偏移量。代码中的这一点是否影响斯塔夫的问题。 –

回答

2

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

我看到两种可能性会在这里:

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

回复:MyStream不是每次

在开始,将MyStream参数设置过?还是被重新用于新的流?您的代码只在构造函数中“重新启动”,因此请确保当您更改传入流时,对象将被丢弃并重新构建。

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

如果将静态变量添加到MyStream.Read和方法的入口/出口中,您可以测试意外的递归。如果它们不匹配,则FileStream正在进行内部(意外递归)调用。

-Jesse