并行任务共享全局变量

时间:2013-06-05 16:25:44

标签: c# task-parallel-library

您好我是使用并行任务的新手。我有一个功能,我需要并行运行多次。下面是显示此内容的虚拟代码,

public MyClass GlobalValue;

static void Main(string[] args)
{
    Task task1 = Task.Factory.StartNew(() => SaveValue());
    Task task2 = Task.Factory.StartNew(() => SaveValue());
    Task task3 = Task.Factory.StartNew(() => SaveValue());
}

public void SaveValue()
{
    string val = GetValueFromDB();
    if (GlobalValue == NULL)
    {
        GlobalValue = New MyClass(val);
    }
    else if (GlobalValue.Key != val)
    {
        GlobalValue = New MyClass(val);
    }

    string result = GlobalValue.GetData();
}

现在每次调用GlobalValue = New GlobalValue(val)行。请帮助我。我认为全局变量存在问题。

2 个答案:

答案 0 :(得分:2)

您需要同步对共享数据的访问权限,因为每个线程都会尝试同时访问它,并且看到它为空,然后全部将分配。

请注意,同步(如果通过锁定完成)可能会导致三个线程有效地顺序运行,因为一次只有一个线程可以进入锁定。

答案 1 :(得分:0)

好吧,为什么不这样做

static void Main()
{
    var tasks = new[]
        {
            Task.Factory.StartNew(() => YourFunction()),
            Task.Factory.StartNew(() => YourFunction()),
            Task.Factory.StartNew(() => YourFunction())
        };

    Task.WaitAll(tasks)
}

public static string YourFunction()
{
    var yourClass = new MyClass(GetValueFromDB());
    return yourClass.GetData();
}

我不明白为什么你需要GlobalValueMyClass实例化是否昂贵?更值得注意的是,你没有对结果做任何事情,所以一切都没有实际意义。


由于功能可用,假设您使用的是.Net 4.5(c#5.0),您可以这样做

static void Main()
{
    await Task.WhenAll(YourFunction(), YourFunction(), YourFunction());
}

public async Task<string> YourFunction()
{
    return new MyClass(GetValueFromDB()).GetData();
}

为了便于说明,您仍然可以使用全局变量,但它会大大降低并行化的好处。您只需确保序列化对共享状态的访问或使用为您执行此操作的线程安全类型。

改编自你的例子,

public void SaveValue()
{
    string val = GetValueFromDB();
    MyClass thisValue;
    lock (this.GlobalValue)
    {
        if (this.GlobalValue == NULL)
        {
            this.GlobalValue = new MyClass(val);
        }
        else if (this.GlobalValue.Key != val)
        {
            this.GlobalValue = new MyClass(val);
        }

        thisValue = this.GlobalValue
    }

    string result = thisValue.GetData();
}