首页 > 解决方案 > 线程间共享方法

问题描述

我有一个Func这样的:

int loopMax = 10, taskMax = 10;
int executionCounter = 0;

Func<int> calculator = new Func<int>(() =>
{
    executionCounter++;
    int result = 0;
    for (int i = 0; i < loopMax; i++)
    {
        Thread.Sleep(100);
        if (result + i >= int.MaxValue)
            result = 0;
        result += i;
    }
    return result;
});

可以由多个线程调用。例如像这样:

Task[] tasks = new Task[taskMax];
for (int i = 0; i < taskMax; i++)
{
    tasks[i] = Task.Run(() => _=calculator());
}
Task.WaitAll(tasks);

我需要calculator在所有线程之间共享该函数,并使该函数仅被调用一次。事实上,executionCounter运行此代码后变量的值应该保持为 1,并且所有线程应该具有相同的返回值。

更新 1

我想我可以解决这个问题,如果我找到一种方法来服务第一个线程并阻塞所有其他线程,并且在第一个线程的方法调用完成后,将方法结果发送给其他线程并取消它们,以防止它们calculator再次调用。

在方法内部使用lock也不是我想要的,因为在这种情况下,计算器再次被多次调用......

标签: c#multithreadingtask-parallel-library

解决方案


看来你需要这Lazy<T>门课。此类提供对延迟初始化的支持。以下是您可以如何使用它:

Lazy<int> lazyCalculator = new Lazy<int>(calculator);

Task[] tasks = new Task[taskMax];
for (int i = 0; i < taskMax; i++)
{
    tasks[i] = Task.Run(() => _ = lazyCalculator.Value);
}
Task.WaitAll(tasks);

构造实例时Lazy,它可以采用可选LazyThreadSafetyMode参数。此参数的默认值为ExecutionAndPublication,其行为描述如下:

锁用于确保只有单个线程可以Lazy<T>以线程安全的方式初始化实例。


推荐阅读