gpt4 book ai didi

c# - 不是每一个 IProgress 的结果都从任务中出来

转载 作者:太空宇宙 更新时间:2023-11-03 10:22:25 26 4
gpt4 key购买 nike

考虑以下实现,一个方法接受 IProgress<int> , 迭代超过 10000 个对象。 numbers array 变量返回 10000 个对象,但是 IProgress<int>仅报告 9970 - 9980 个对象。每次运行都会有所不同,因此有些会“丢失”。

    protected async override Task<int[]> CollectDataAsyncImpl(IProgress<int> progress) {                
return await Task.Run<int[]>(() => {

var numbers = new List<int>();

foreach (var idx in new Int32Range(1, 10000).AsEnumerable().Index()) {

numbers.Add(idx.Value);

if (progress != null) {
progress.Report(idx.Value);
}

}

return numbers.ToArray();
});
}

作为引用,这是我运行的测试。它在第三个断言处失败 Assert.Equal(10000, result[9999]); .

[Fact]
async void ReportsProgress() {
var sut = new IntegerCollector();
var result = new List<int>();
var output = await sut.CollectDataAsync(new Progress<int>(i => result.Add(i)));
Assert.Equal(10000, output.Length);
Assert.Equal(1, result[0]);
Assert.Equal(10000, result[9999]);
}

显然我做错了什么,或者我不了解任务/线程的内部结构。是我执行的 IProgress<int>new Progress<int>(i => result.Add(i))不正确?我应该使该线程安全吗?如果是,我该怎么做?

GitHub 有您可以在需要时克隆和测试的代码:https://github.com/KodeFoxx/Kf.DataCollection/tree/master/Source/Kf.DataCollection

最佳答案

这可能是因为如何Progress<T>实现。创建时,Progress<T>捕获同步上下文并使用它来执行 i => result.Add(i) .由于您正在运行测试,因此我假设没有同步上下文。在这种情况下 Progress<T>使用默认 SynchronizationContext ,它将工作项发布到线程池 ( ThreadPool.QueueUserWorkItem )。您的任务在线程池处理所有排队的项目之前完成,它完美地解释了结果不一致。

检查是否是这种情况的简单方法:更改 IProgress<int> Action<int> 的参数并通过 i => result.Add(i)直接委托(delegate),不用 Progress<T> 包裹.

关于c# - 不是每一个 IProgress<int> 的结果都从任务中出来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32917597/

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