- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
考虑以下实现,一个方法接受 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/
您能告诉我一种从 Java 执行进程而不管底层操作系统如何的方法吗?例如。 Process p = Runtime.getRuntime().exec("cmd /c mvn clean instal
我编写了从 MediaStore.Video.Media.EXTERNAL_CONTENT_URI 中获取视频的代码和 INTERNAL_CONTENT_URI使用 context.getConten
我是一名优秀的程序员,十分优秀!