2012-05-26 76 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