这是我的课程:
public class UnusedRolesOccurrence
{
public string Username { get; set; }
public string FullName { get; set; }
public string Role { get; set; }
public int[] Month { get { return month; } set { month = value; } }
private static int[] month = new int[12];
}
这是我要在int数组中填充值的地方:
Parallel.ForEach(unusedrolesoccurrence, (UnusedRolesOccurrence item) =>
{
try
{
lock (listLock)
{
int count = tmp.Count(x => x.Username == item.Username && x.Role == item.Role);
item.Month[month] = count;
if (count > 2)
{
Debug.WriteLine($"{item.Username},{item.Role},{month}={count},{item.Month[month]}");
}
}
}
catch
{
//
}
});
List<unusedrolesoccurrence>
已预先填充了数据。在开始foreach之前,月数组是[0,0,0,0,0,0,0,0,0,0,0,0],int[] arr_month = new int[12];
。
tmp
也是List<t>
。
什么不起作用:在循环期间,计数以及item.Month[month]
的值都是正确的。但不在目标List<UnusedRolesOccurrence>
中。所有Month与循环中处理的最后一个计数的值相同,例如[3,0,3,0,0,0,0,0,0,0,0,0]或[0,1,1,0,0,0,0,0,0,0,0,0 ]。而且因为并行,所以结果总是不同的。
我将int[]
更改为public Dictionary<int, int> Month { get; set; }
进行测试,但是行为相同。
此处的示例代码(带有//带有字典的辅助尝试,结果相同)
public class UnusedRoles
{
public string Username { get; set; }
public string Role { get; set; }
public int Month { get; set; }
}
public class UnusedRolesOccurrence
{
public string Username { get; set; }
public string Role { get; set; }
//public Dictionary<int, int> Month { get; set; }
public int[] Month { get { return month; } set { month = value; } }
public int[] month = new int[12];
}
public List<UnusedRoles> unusedroles = new List<UnusedRoles>();
public List<UnusedRolesOccurrence> unusedrolesoccurrence = new List<UnusedRolesOccurrence>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Run();
}
public async void Run()
{
unusedroles.Clear();
unusedrolesoccurrence.Clear();
Dictionary<int, int> dictionary_month = new Dictionary<int, int>();
//for (int i = 0; i < 12; i++) { dictionary_month.Add(i, 0); }
int[] arr_month = new int[12];
unusedroles.Add(new UnusedRoles { Username = "User1", Role = "A", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User1", Role = "A", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User1", Role = "B", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User2", Role = "A", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User2", Role = "B", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User2", Role = "B", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User3", Role = "C", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User3", Role = "C", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User3", Role = "C", Month = 0 });
unusedroles.Add(new UnusedRoles { Username = "User4", Role = "A", Month = 0 });
var tmp = unusedroles.Select(x => new { x.Username, x.Role }).Distinct();
foreach (var item in tmp)
{
unusedrolesoccurrence.Add(new UnusedRolesOccurrence
{
//Username = item.Username, Role = item.Role, Month = dictionary_month
Username = item.Username, Role = item.Role, Month = arr_month
});
}
var result = await Find(0);
foreach (var item in unusedrolesoccurrence)
{
//string line = "";
//foreach (var pair in item.Month) {
// line = $"{line},{pair.Value}";
//}
string line = $"{item.Username},{item.Role}";
foreach (int i in item.Month)
{
line = $"{line},{i}";
}
//Debug.WriteLine($"{item.Username},{item.Role}{line}");
Debug.WriteLine($"{line}");
}
}
public async Task<bool> Find(int month)
{
await Task.Run(() =>
{
Parallel.ForEach(unusedrolesoccurrence, (UnusedRolesOccurrence item) =>
{
int count = unusedroles.Count(x => x.Username == item.Username && x.Role == item.Role &&x.Month == month);
item.Month[month] = count;
Debug.WriteLine($"{item.Username},{item.Role},count={count},item.Month[{month}]={item.Month[month]}");
});
});
return true;
}
答案 0 :(得分:1)
TL; DR:您的月份数组是静态的,请不要这样做。
在您设置的并发操作期间,该类的所有所有实例共享该类UnusedRolesOccurrence
的以下成员。
private static int[] month = new int[12];
删除static关键字,UnusedRolesOccurrence
的每个实例将有其自己的.month
数组。
注意:您在此代码中可能还有其他问题,但是您的问题来自此处的问题。
答案 1 :(得分:0)
它正在这样工作。
之前:
int[] arr_month = new int[12];
var tmp = unusedroles.Select(x => new { x.Username, x.Role }).Distinct();
foreach (var item in tmp)
{
unusedrolesoccurrence.Add(new UnusedRolesOccurrence
{
//Username = item.Username, Role = item.Role, Month = dictionary_month
Username = item.Username, Role = item.Role, Month = arr_month
});
}
之后:
var tmp = unusedroles.Select(x => new { x.Username, x.Role }).Distinct();
foreach (var item in tmp)
{
unusedrolesoccurrence.Add(new UnusedRolesOccurrence
{
//Username = item.Username, Role = item.Role, Month = dictionary_month
Username = item.Username, Role = item.Role, Month = new int[12]
});
}