This is a severe problem in my application for some months with out finding any good solution. I noticed that C# manage the way Stream class is streaming in WCF, without considering my configuration.
Firstly, I have a class that inherit from FileStream so I can watch how much was read until now from the client side at anytime:
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; } }
Secondly, below is my service method of reading the client's stream that contain the file. My main problem is that FileStreamWatching.Read does not start for each time I summon it from this method below, instead FileStreamWatching.Read start one time for each X times I call it.. Strange.
*Look at the out put later
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(); } } }
This is the output at the client side for each time FileStreamWatching.Read is activated:(Remmber the buffer lenght is only 1000!)
Arr Lenght: 256, Read: 256
Arr Lenght: 4096, Read: 4096
Arr Lenght: 65536, Read: 65536
....Until the file transfare is complete.
Problems:
My goals:
Controling on how much I reacive from the client for each read.
The FileStreamWatching.Read will start each time I call it from the service.
My Client configuration:
<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>
My service configuration (There is no configuration file here):
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();