62,266
社区成员
发帖
与我相关
我的任务
分享实际工作中,发现一个并发导致数据丢失的问题,大家一起看看是否有解决办法?
/// <summary>
/// 测试线程安全的队列
/// </summary>
public class TestConcurrentQueue
{
public static void DoTest()
{
//构造测试数据
List<IdNameModel> list = new List<IdNameModel>();
for (int i = 0; i < 100; i++)
{
list.Add(new IdNameModel()
{
Id = i + 1,
Name = "用户" + i
});
}
_ = RunWork(list);
}
public async static Task RunWork(List<IdNameModel> list)
{
//装入队列中
ConcurrentQueue<IdNameModel> queue = new ConcurrentQueue<IdNameModel>();
foreach (IdNameModel item in list)
{
queue.Enqueue(item);
}
int numInOneTimes = 10; //并发一次处理数据条数
Task[] tasks;
List<int> ids = new List<int>();
IdNameModel? dataItem = null;
while (!queue.IsEmpty)
{
ids = new List<int>();
tasks = new Task[queue.Count > numInOneTimes ? numInOneTimes : queue.Count];
for (var i = 0; i < numInOneTimes; i++)
{
if (queue.TryDequeue(out dataItem))
{
IdNameModel innerItem = dataItem;
tasks[i] = Task.Run(async () =>
{
ids.Add(innerItem.Id);
await Task.Delay(2000);
return;
});
}
}
await Task.WhenAll(tasks);
Console.WriteLine(string.Format("操作完成共【{0}】条数据,编号为【{1}】的数据列表!", ids.Count, string.Join(",", ids)));
}
}
}
public class IdNameModel
{
public int Id { get; set; }
public string? Name { get; set; }
}
实际输出的操作数据条数,始终比预定目标的1~100有差距,还在追查问题中...
唉,发现了,原来是我用了个不安全的List对象,换成ConcurrentBag对象就达到目的了。