WCF Streaming - ограничение скорости
Это серьезная проблема в моем заявлении в течение нескольких месяцев без поиска какого-либо хорошего решения. Я заметил, что C# управляет потоковым потоком класса в 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!)
Длина: 256, Читать: 256
Длина: 4096, чтение: 4096
Длина: 65536, прочитано: 65536
Длина: 65536, прочитано: 65536
Длина: 65536, прочитано: 65536
Длина: 65536, прочитано: 65536
.... Пока не завершена передача файла.
Проблемы:
- Длина буфера, который я привел к методу чтения, не равна 256/4096/65536. Это 1000
- Класс Read from FileStreamWatching не запускается каждый раз, когда я вызываю его из службы.
Мои цели:
Контроль за тем, насколько я реагирую от клиента на каждое чтение.
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();
1 ответ
Re: почему 256/4K/65535?
Я вижу две возможности здесь:
- База
FileStream
делает свою собственную внутреннюю буферизацию. Это может быть внутренний звонокread(array,offset,length)
заполнить его внутренний буфер, а затем вернуть часть, которую вы просили. Внутренние вызовы заканчивают тем, что были рекурсивными, пока это не прочитало весь файл. Тогда ваше переопределение перестает отображать что-либо. - Есть и другие
stream.read()
подписи, которые вы не показываете как переопределенные. Если какой-либо путь кода заканчивается вызовом одного из другихread
методы, тогда ваши счета будут выключены.
Re: MyStream не запускается каждый раз
Это MyStream
аргумент когда-либо располагал? или это повторно для нового потока? Ваш код только "перезапускается" в конструкторе, поэтому убедитесь, что объект удаляется и перестраивается при изменении входящих потоков.
Вы можете проверить рекурсивный случай EOF, также показывая что-то, когда EOF достигнут.
Вы можете проверить наличие неожиданной рекурсии, если добавите статические переменные, считая оба вызова приложения MyStream.Read
и метод входа / выхода. Если они не совпадают, то FileStream
совершает внутренние (случайно рекурсивные) вызовы.
-Jesse