C# 使用列表的相同状态获取多个计数

C# 使用列表的相同状态获取多个计数,c#,.net,linq,C#,.net,Linq,我有这样的代码: count = taskList.Count(x => x.IsCompleted); successfulCount = taskList.Count(x => x.IsCompleted && x.Result == true); failedCount = taskList.Count(x => x.IsCompleted && x.Result == false); Console.Write($"\r {c

我有这样的代码:

count = taskList.Count(x => x.IsCompleted);
successfulCount = taskList.Count(x => x.IsCompleted && x.Result == true);
failedCount = taskList.Count(x => x.IsCompleted && x.Result == false);
Console.Write($"\r {count} out of {calls} calls made. {successfulCount} successful, {failedCount} failed.");
然后我就这样使用它:

count = taskList.Count(x => x.IsCompleted);
successfulCount = taskList.Count(x => x.IsCompleted && x.Result == true);
failedCount = taskList.Count(x => x.IsCompleted && x.Result == false);
Console.Write($"\r {count} out of {calls} calls made. {successfulCount} successful, {failedCount} failed.");
问题是任务列表正在另一个线程中更新。所以我最终收到了这样的信息:

count = taskList.Count(x => x.IsCompleted);
successfulCount = taskList.Count(x => x.IsCompleted && x.Result == true);
failedCount = taskList.Count(x => x.IsCompleted && x.Result == false);
Console.Write($"\r {count} out of {calls} calls made. {successfulCount} successful, {failedCount} failed.");
777843个电话中有48个。96成功,0失败

我知道它为什么这样做。在我计算
计数
和计算
成功计数
之间,我完成了更多的任务

但向我的测试人员展示(这是一个测试线束)仍然有点奇怪,因此,如果可以在不减慢我观察的速度的情况下进行修复,那么我希望修复它


有没有一种方法可以在一个查询中发出3个count调用,从而更有可能得到一致的结果?(我似乎不太可能,但我想我会问。)

你可以做以下事情

var result = taskList.Where(x => x.IsCompleted)
    .GroupBy(x => x.Result)
    .ToDictionary(x => x.Key, x => x.Count());

var successfulCount = result.TryGetValue(true, out var success) ? success : 0;
var failedCount = result.TryGetValue(false, out var failed) ? failed : 0;
var count = successfulCount + failedCount;

这将对
结果
列表中的项目进行分组,并创建计数字典。然后,您可以获得成功计数和失败计数,并通过添加它们来创建总数。

您可以执行以下操作

var result = taskList.Where(x => x.IsCompleted)
    .GroupBy(x => x.Result)
    .ToDictionary(x => x.Key, x => x.Count());

var successfulCount = result.TryGetValue(true, out var success) ? success : 0;
var failedCount = result.TryGetValue(false, out var failed) ? failed : 0;
var count = successfulCount + failedCount;
这将对
结果
列表中的项目进行分组,并创建计数字典。然后,您可以获得成功计数和失败计数,并通过添加它们来创建总数。

只是有价值答案的一个变体,拍一张快照

var current = taskList.Select(x => (x.IsCompleted, x.Result)).ToList();
count = current.Count(x => x.IsCompleted)
successfulCount = current.Count(x => x.IsCompleted && x.Result == true);
failedCount = current .Count(x => x.IsCompleted && x.Result == false);
只是有价值答案的一个变体,拍一张快照

var current = taskList.Select(x => (x.IsCompleted, x.Result)).ToList();
count = current.Count(x => x.IsCompleted)
successfulCount = current.Count(x => x.IsCompleted && x.Result == true);
failedCount = current .Count(x => x.IsCompleted && x.Result == false);

不确定是否是这种情况,但如果
任务列表
列表
则不是线程安全的。您可以尝试使用
System.Collections.Concurrent
命名空间下的
ConcurrentBag
ConcurrentDictionary
。另一个选项是
锁定
静态对象以操作列表。拍摄快照
var current=taskList。选择(x=>(x.IsCompleted,x.Result))不确定是否是这种情况,但如果
任务列表
列表
则不是线程安全的。您可以尝试使用
System.Collections.Concurrent
命名空间下的
ConcurrentBag
ConcurrentDictionary
。另一个选项是
锁定
静态对象以操作列表。拍摄快照
var current=taskList。选择(x=>(x.IsCompleted,x.Result))
您是否打算包含一个
列表
,因为如果不是这样,每次
计数
呼叫都会重复原始更改列表。@juharr ah yupThank您的答案!如果《计数词典》不起作用,我会回到这一点上来。(我的列表可能有200K个任务,所以完整的快照可能会影响我的负载测试。)你是不是想包括一个
列表
,因为如果不是这样,每次
计数
调用都会重复原始的更改列表。@juharr ah yupThank谢谢你的回答!如果《计数词典》不起作用,我会回到这一点上来。(我的列表可能有200000个任务,所以完整的快照可能会影响我的负载测试。)谢谢你的回答!我的任务列表可能非常大(200K个任务)。我喜欢捕获计数字典的想法。谢谢你的回答!我的任务列表可能非常大(200K个任务)。我喜欢只捕获计数字典的想法。