2012-05-26 41 views
7

Đây là một vấn đề nghiêm trọng trong ứng dụng của tôi trong một vài tháng với việc tìm ra bất kỳ giải pháp tốt nào. Tôi nhận thấy rằng C# quản lý cách lớp Dòng đang phát trực tuyến trong WCF, mà không xem xét cấu hình của tôi.WCF Streaming - Giới hạn tốc độ

Thứ nhất, tôi có một lớp kế thừa từ FileStream để tôi có thể xem có bao nhiêu đã được đọc cho đến nay từ phía khách hàng bất cứ lúc nào:

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

Thứ hai, dưới đây là phương pháp dịch vụ của tôi đọc dòng của khách hàng có chứa tệp. Vấn đề chính của tôi là FileStreamWatching.Read không bắt đầu cho mỗi lần tôi triệu hồi nó từ phương thức này bên dưới, thay vào đó FileStreamWatching.Read bắt đầu một lần cho mỗi lần X tôi gọi nó .. Lạ.

* Nhìn vào ra đặt sau

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

Đây là sản lượng tại phía khách hàng cho mỗi lần FileStreamWatching.Read được kích hoạt: (Remmber chiều dài đệm được chỉ có 1000!)

Giờ đến Chiều dài: 256, đọc: 256


Giờ đến Chiều dài: 4096, đọc: 4096


Giờ đến Chiều dài: 65536, đọc: 65536


Giờ đến Chiều dài: 65536, đọc: 65536


Giờ đến Chiều dài: 65536, Đọc: 65536


Giờ đến Chiều dài: 65536, đọc: 65536


.... Cho đến file transfare hoàn tất.

vấn đề:

  1. Các Chiều dài của bộ đệm I đưa đến đọc phương pháp isnt 256/4096/65536. Nó là 1000.
  2. Đọc từ lớp FileStreamWatching không khởi động mỗi khi tôi gọi nó từ dịch vụ.

Mục tiêu của tôi:

  1. Controling vào bao nhiêu tôi reacive từ khách hàng đối với từng đọc.

  2. FileStreamWatching.Read sẽ bắt đầu mỗi lần tôi gọi nó từ dịch vụ.

cấu hình Khách hàng của tôi:

<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> 

cấu hình dịch vụ My (Không có tập tin cấu hình ở đây):

 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 (buffer, 0, buffer.Length) - không nên thặng dư bù đắp sau mỗi cuộc gọi? – Tisho

+0

@Tuy nhiên ứng dụng có thể thay đổi bù trừ cho mỗi cuộc gọi. Cho dù nó có hay không không ảnh hưởng đến câu hỏi của Stav vào thời điểm này trong mã. –

Trả lời

2

lại: tại sao 256/4K/65535 ?

tôi thấy hai khả năng xảy ra ở đây:

  • Các cơ sở FileStream đang làm đệm nội bộ riêng của mình. Nó có thể được gọi nội bộ read(array,offset,length) để điền vào bộ đệm bên trong của nó, sau đó truyền lại phần bạn đã yêu cầu. Các cuộc gọi nội bộ kết thúc được đệ quy, cho đến khi nó đã đọc toàn bộ tập tin. Sau đó, ghi đè của bạn dừng hiển thị bất cứ điều gì.
  • stream.read() chữ ký khác mà bạn không hiển thị là bị ghi đè. Nếu bất kỳ đường dẫn mã nào kết thúc bằng cách gọi một trong các phương thức read khác thì số lượng của bạn sẽ bị tắt.

lại: MyStream không bắt đầu lại mỗi lần

là đối số MyStream bao giờ xử lý? hoặc được sử dụng lại cho luồng mới? Mã của bạn chỉ "khởi động lại" trong hàm tạo, vì vậy hãy chắc chắn đối tượng được xử lý và xây dựng lại khi bạn thay đổi luồng đến.

Bạn có thể kiểm tra trường hợp EOF đệ quy bằng cách hiển thị nội dung nào đó khi đạt được EOF.

Bạn có thể kiểm tra đệ quy không mong muốn nếu bạn thêm các biến tĩnh đếm cả ứng dụng gọi đến MyStream.Read và nhập/thoát phương thức. Nếu không khớp, thì FileStream sẽ thực hiện cuộc gọi nội bộ (vô tình đệ quy).

-Jesse

Các vấn đề liên quan