Skip to content

Commit b88a3b4

Browse files
committed
😊 改进 带应用速率限制的流,尽可能减少误差
1 parent 71172c6 commit b88a3b4

File tree

3 files changed

+20
-18
lines changed

3 files changed

+20
-18
lines changed

src/HttpAgent/src/HttpAgent.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6934,14 +6934,14 @@
69346934
<member name="F:HttpAgent.RateLimitedStream._innerStream">
69356935
<inheritdoc cref="T:System.IO.Stream" />
69366936
</member>
6937-
<member name="F:HttpAgent.RateLimitedStream._startTime">
6937+
<member name="F:HttpAgent.RateLimitedStream._stopwatch">
69386938
<summary>
6939-
流开始读取的时间点
6939+
用于精确计时的 <see cref="T:System.Diagnostics.Stopwatch" /> 实例
69406940
</summary>
69416941
</member>
6942-
<member name="F:HttpAgent.RateLimitedStream._totalBytesRead">
6942+
<member name="F:HttpAgent.RateLimitedStream._totalBytesProcessed">
69436943
<summary>
6944-
到目前为止已读取的总字节数
6944+
到目前为止已读取或写入的总字节数
69456945
</summary>
69466946
</member>
69476947
<member name="M:HttpAgent.RateLimitedStream.#ctor(System.IO.Stream,System.Int32)">
@@ -6993,7 +6993,7 @@
69936993
<summary>
69946994
根据设定的速率限制调整读写操作的速度
69956995
</summary>
6996-
<param name="bytesToRead">本次操作将处理的字节数</param>
6996+
<param name="bytesToProcess">本次操作将处理的字节数</param>
69976997
</member>
69986998
<member name="T:HttpAgent.ServerSentEventsData">
69996999
<summary>

src/HttpAgent/src/Models/RateLimitedStream.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ public sealed class RateLimitedStream : Stream
1818
internal readonly Stream _innerStream;
1919

2020
/// <summary>
21-
/// 流开始读取的时间点
21+
/// 用于精确计时的 <see cref="Stopwatch" /> 实例
2222
/// </summary>
23-
internal readonly DateTime _startTime;
23+
internal readonly Stopwatch _stopwatch = new();
2424

2525
/// <summary>
26-
/// 到目前为止已读取的总字节数
26+
/// 到目前为止已读取或写入的总字节数
2727
/// </summary>
28-
internal long _totalBytesRead;
28+
internal long _totalBytesProcessed;
2929

3030
/// <summary>
3131
/// <inheritdoc cref="RateLimitedStream" />
@@ -49,8 +49,8 @@ public RateLimitedStream(Stream innerStream, int bytesPerSecond)
4949
_innerStream = innerStream;
5050
_bytesPerSecond = bytesPerSecond;
5151

52-
// 记录当前时间作为开始时间
53-
_startTime = DateTime.UtcNow;
52+
// 启动 Stopwatch 来开始计时
53+
_stopwatch.Start();
5454
}
5555

5656
/// <inheritdoc />
@@ -119,17 +119,17 @@ protected override void Dispose(bool disposing)
119119
/// <summary>
120120
/// 根据设定的速率限制调整读写操作的速度
121121
/// </summary>
122-
/// <param name="bytesToRead">本次操作将处理的字节数</param>
123-
internal async Task ApplyRateLimitAsync(int bytesToRead)
122+
/// <param name="bytesToProcess">本次操作将处理的字节数</param>
123+
internal async Task ApplyRateLimitAsync(int bytesToProcess)
124124
{
125125
// 自开始以来经过的时间(秒)
126-
var elapsedSeconds = (DateTime.UtcNow - _startTime).TotalSeconds;
126+
var elapsedSeconds = _stopwatch.ElapsedMilliseconds / 1000.0;
127127

128128
// 根据速率预期应读取的字节数
129129
var totalBytesExpected = elapsedSeconds * _bytesPerSecond;
130130

131131
// 计算实际与预期之差
132-
var bytesOverLimit = _totalBytesRead + bytesToRead - totalBytesExpected;
132+
var bytesOverLimit = _totalBytesProcessed + bytesToProcess - totalBytesExpected;
133133

134134
if (bytesOverLimit > 0)
135135
{
@@ -139,7 +139,7 @@ internal async Task ApplyRateLimitAsync(int bytesToRead)
139139
await Task.Delay(delayMilliseconds).ConfigureAwait(false);
140140
}
141141

142-
// 更新已读取的总字节数
143-
_totalBytesRead += bytesToRead;
142+
// 更新已处理的总字节数
143+
_totalBytesProcessed += bytesToProcess;
144144
}
145145
}

src/HttpAgent/test/RateLimitedStreamTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ public void New_ReturnOK()
2525
using var fileStream = File.OpenRead(filePath);
2626
using var rateLimitedStream = new RateLimitedStream(fileStream, 5);
2727

28-
Assert.Equal(0, rateLimitedStream._totalBytesRead);
28+
Assert.Equal(fileStream, rateLimitedStream._innerStream);
29+
Assert.Equal(0, rateLimitedStream._totalBytesProcessed);
2930
Assert.Equal(fileStream.CanRead, rateLimitedStream.CanRead);
3031
Assert.Equal(fileStream.CanSeek, rateLimitedStream.CanSeek);
3132
Assert.Equal(fileStream.CanWrite, rateLimitedStream.CanWrite);
3233
Assert.Equal(fileStream.CanTimeout, rateLimitedStream.CanTimeout);
3334
Assert.Equal(21, rateLimitedStream.Length);
3435
Assert.Equal(fileStream.Position, rateLimitedStream.Position);
36+
Assert.NotNull(rateLimitedStream._stopwatch);
3537
}
3638

3739
[Fact]

0 commit comments

Comments
 (0)