首页 > 解决方案 > 如何管理在所有任务中使用相同变量的流程

问题描述

我正在创建 10 个任务,每个任务都会创建一个递增的数字。然后我排队到ConcurrentQueue结果i队列中有 10 个数字,但每个数字的值都是 10。

如何设置队列中的每个数字具有不同的值(0 到 9)。TaskTest() 方法也应该在 10 秒内完成。

public async void TaskTest()
{
    ConcurrentQueue<int> queue;
    queue = await GetNumbers();
}
private async Task<ConcurrentQueue<int>> GetNumbers()
{
    ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
    List<Task> tasks = new List<Task>();

    int i = 0;
    while (i<10)
    {
        tasks.Add(Task.Factory.StartNew(() =>
        {
            var number = CreateNumber(i);
            queue.Enqueue(number);
        }));
        Interlocked.Increment(ref i);
    }
    
    foreach (var t in tasks)
    {
        await t;
    }
    return queue;
}
private int CreateNumber(int i)
{
    Thread.Sleep(1000);
    return i;
}

结果:

在此处输入图像描述

标签: c#asynchronousasync-await

解决方案


关于while (i<10),如果您事先知道迭代次数,那么您真的应该使用for循环而不是while.

使用for循环,或者Enumerable.Range您无需担心i以线程安全的方式进行操作:

private async Task<ConcurrentQueue<int>> GetNumbers()
{
    ConcurrentQueue<int> queue = new ConcurrentQueue<int>();

    Task EnqueOnThreadPoolAsync(int i) => Task.Run(() => queue.Enqueue(CreateNumber(i)));

    await Task.WhenAll(Enumerable.Range(0, 10).Select(EnqueOnThreadPoolAsync));

    return queue;
}

推荐阅读