How can I manage an process that using same variable in all tasks

Viewed 99

I'm creating 10 tasks and every task creates a number with increment. Then i enqueue to ConcurrentQueue As a result i there are 10 numbers in the queue but every numbers value is 10.

How can I set every numbers in queue have different value (0 to 9). Also the TaskTest() method should complete in less than 10 second.

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;
}

The result:

enter image description here

1 Answers

Regarding while (i<10), if you know the number iterations up front, you should really be using a for loop rather than a while.

Using a for loop or Enumerable.Range you don't need to worry about manipulating i in a thread safe way:

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;
}
Related