camm
camm

Reputation: 17

How to add to value from different tasks

So let's say I had something that looked like this (example code):

public int val = 0;
public Task[] Tasks = new Task[3];

private void Run()
{
    for (int i = 0; i <= Tasks.Count(); i++)
    {
        Tasks[i] = Task.Run(() =>
        {
            changeValue(val);
        });
    }
    foreach (var task in Tasks)
    {
        try
        {
            task.Wait();
        }
        catch { }
    }
}

public static void changeValue(int value)
{
    for (int i = 0; i <= 100; i++)
    {
        value++;
        MessageBox.Show(value.ToString());
    }
}

In my case this caps the value at 100 because each task is changing it independently, but I want it to cap at 300 because there are 3 tasks (for this example) and I want them to change the value together.

Does anyone know what could help me with this? I've tried doing public volatile int val, and I tried making a lock method that changes the value but nothing worked.

Upvotes: 0

Views: 378

Answers (1)

Michael
Michael

Reputation: 1276

You are passing value by value, so val would never changed. This code snippet makes no sense for me, but passing by reference and Interlocked would do the job.

public class C1
{
    public int Val => val;
    private int val = 0;
    public Task[] Tasks = new Task[3];  // Why is this public?

    public async Task Run()
    {
        // <= is wrong!
        for (int i = 0; i < Tasks.Length; i++)
        {
            Tasks[i] = Task.Run(() =>
            {
                C2.ChangeValue(ref val);
            });
        }
        await Task.WhenAll(Tasks);
    }
}

public class C2
{
    public static void ChangeValue(ref int value)
    {
        // < instead of <=
        for (int i = 0; i < 100; i++)
        {
            System.Threading.Interlocked.Add(ref value, 1);
            Console.WriteLine(value);  // Or Messagebox
        }
    }
}

public class Program
{
    private static async Task Main(string[] args)
    {
        var c1 = new C1();
        await c1.Run();
    }
}

Upvotes: 3

Related Questions