首页 > 解决方案 > 如何从不同的任务中增加价值

问题描述

所以假设我有一些看起来像这样的东西(示例代码):

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

在我的情况下,这将值上限为 100,因为每个任务都在独立更改它,但我希望它上限为 300,因为有 3 个任务(对于此示例),我希望它们一起更改值。

有谁知道什么可以帮助我解决这个问题?我已经尝试过public volatile int val,并且尝试制作一个更改值的锁定方法,但没有任何效果。

标签: c#multithreadingtask

解决方案


您按值传递值,因此 val 永远不会改变。这个代码片段对我来说没有意义,但是通过引用传递和联锁就可以了。

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

推荐阅读