gpt4 book ai didi

c# - System.Progress 错误的调用顺序

转载 作者:太空狗 更新时间:2023-10-30 00:50:15 24 4
gpt4 key购买 nike

我正在尝试使用 HttpClient 显示下载进度。为此,我使用 System.Progress<T> .代码如下所示:

long totalRead = 0L;
var buffer = new byte[1024];
bool isMoreToRead = true;
ulong total = (ulong)response.Content.Headers.ContentLength;

while (isMoreToRead)
{
int read = await stream.ReadAsync(buffer, 0, buffer.Length);
if (read == 0)
isMoreToRead = false;
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
totalRead += read;
progress.Report((int) (totalRead*1d / total * 1d * 100) );
}
}

假设订阅看起来像这样:

var progress = new Progress<int>();
progress.ProgressChanged += (sender, i) => Console.WriteLine(i);
client.Download(file, progress).Wait();

但是这样一来,进度顺序就不一致了,像这样:10、20、30、70、15、90、100、80。

这是默认委托(delegate)的行为,还是有其他原因?

最佳答案

Progress<T>.Report是异步的;我的意思是,Report方法不会引发 ProgressChanged在返回之前同步事件。

Progress<T>类捕获 SynchronizationContext 并发布 ProgressChanged 的调用事件到那个捕获的上下文。

在 Winforms、Wpf 等单线程上下文中使用时,您的代码将按预期工作。

在控制台应用程序中,不会有任何 SynchronizationContext,因此 Progress<T>将调用发布到委托(delegate)给 ThreadPool 的默认 SynchronizationContext。 ThreadPool 不保证任何顺序,这就是您看不到同步结果的原因。

我相信您正在控制台应用程序或类似的东西中测试此代码,否则您的代码没有任何问题。

如果你需要IProgress<T>的同步版本,你必须自己动手。

关于c# - System.Progress 错误的调用顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32859473/

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