gpt4 book ai didi

c# - WCF Streaming - 限制速度

转载 作者:太空狗 更新时间:2023-10-29 20:37:15 25 4
gpt4 key购买 nike

这是我应用程序中的一个严重问题,几个月来一直没有找到任何好的解决方案。我注意到 C# 管理 Stream 类在 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


....直到文件传输完成。

问题:

  1. 我带到读取方法的缓冲区长度不是 256/4096/65536。是 1000。
  2. 每次从服务调用时,FileStreamWatching 类的读取都不会启动。

我的目标:

  1. 控制我从客户端每次读取的 react 量。

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

最佳答案

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

我看到这里有两种可能性:

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

回复:MyStream 不是每次都重新开始

是否处理过 MyStream 参数?或者它是否被重新用于新的流?您的代码仅在构造函数中“重新启动”,因此请确保在您更改传入流时处理并重新构造该对象。

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

如果添加统计对 MyStream.Read 的应用程序调用和方法进入/退出的静态变量,则可以测试意外递归。如果它们不匹配,则 FileStream 正在进行内部(意外递归)调用。

-杰西

关于c# - WCF Streaming - 限制速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10769302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com