C# 线程间共享方法

C# 线程间共享方法,c#,multithreading,task-parallel-library,C#,Multithreading,Task Parallel Library,我有这样一个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);

我有这样一个
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);
int-loopMax=10,taskMax=10;
int executionCounter=0;
Func计算器=新Func(()=>
{
executionCounter++;
int结果=0;
对于(int i=0;i=int.MaxValue)
结果=0;
结果+=i;
}
返回结果;
});
可以由多个线程调用。例如:

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);
Task[]tasks=新任务[taskMax];
对于(int i=0;i=calculator());
}
Task.WaitAll(任务);
我需要在所有线程中共享
计算器
函数,并使此函数只被调用一次。事实上,运行此代码后,
executionCounter
变量的值应该保持为1,并且所有线程都应该具有相同的返回值

更新1

我想我可以解决这个问题,如果我找到一种方法来为第一个线程提供服务器,并每隔一个线程阻塞一次,并且在第一个线程的方法调用完成后,将方法结果通知其他线程并取消它们,以防止它们再次调用
计算器


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

看起来您想要的是,任何线程都可以执行
calculator
方法,但此方法只能执行一次。如果这是真的,那么我们将使用
lock
语句

:

lock语句获取给定对象的互斥锁 对象,执行语句块,然后释放锁

例如:

static object lockCalculatorMethod = new object();
static int executionCounter = 0;
static int loopMax = 10;
static int taskMax = 10;


static void Main(string[] args)
{
    Task[] tasks = new Task[taskMax];
    for (int i = 0; i < taskMax; i++)
    {
        tasks[i] = Task.Run(() => _ = Calculator());
    }
    Task.WhenAll(tasks);
}

看起来您想要的是,
计算器
方法可以由任何线程执行,但此方法只能执行一次。如果这是真的,那么我们将使用
lock
语句

:

lock语句获取给定对象的互斥锁 对象,执行语句块,然后释放锁

例如:

static object lockCalculatorMethod = new object();
static int executionCounter = 0;
static int loopMax = 10;
static int taskMax = 10;


static void Main(string[] args)
{
    Task[] tasks = new Task[taskMax];
    for (int i = 0; i < taskMax; i++)
    {
        tasks[i] = Task.Run(() => _ = Calculator());
    }
    Task.WhenAll(tasks);
}

看来你需要上课了。此类提供对延迟初始化的支持。以下是您可以如何使用它:

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);
lazyCalculator=新的Lazy(计算器);
Task[]tasks=新任务[taskMax];
对于(int i=0;i\=lazyCalculator.Value);
}
Task.WaitAll(任务);
当构造一个
惰性
实例时,它可以接受一个可选参数。此参数的默认值为
ExecutionAndPublication
,其行为如下所述:

锁用于确保只有单个线程可以以线程安全的方式初始化
惰性
实例


看来你需要上课了。此类提供对延迟初始化的支持。以下是您可以如何使用它:

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);
lazyCalculator=新的Lazy(计算器);
Task[]tasks=新任务[taskMax];
对于(int i=0;i\=lazyCalculator.Value);
}
Task.WaitAll(任务);
当构造一个
惰性
实例时,它可以接受一个可选参数。此参数的默认值为
ExecutionAndPublication
,其行为如下所述:

锁用于确保只有单个线程可以以线程安全的方式初始化
惰性
实例


如果我没听错的话。。您希望一组线程执行同一个函数,但您也希望该函数只执行一次?这在逻辑上是不可能的。@franzgleichman是的,确实是我想要这个,你不明白“我想要它由多个线程执行”和“我想要它只执行一次”是多么矛盾吗?两者兼得是不可能的。。。。看起来你正在试图解决一个你还没有意识到的问题。那么:你到底想用这个实现什么?也许他把“一次”这个词和“同时”这个词混淆了?@Franzgleichann我考虑过这个问题,是否有可能实现这样的场景……我考虑过ReaderWriterLock,信号量,生产者消费者,但无法找到解决方法…如果我理解正确的话。。您希望一组线程执行同一个函数,但您也希望该函数只执行一次?这在逻辑上是不可能的。@franzgleichman是的,确实是我想要这个,你不明白“我想要它由多个线程执行”和“我想要它只执行一次”是多么矛盾吗?两者兼得是不可能的。。。。看起来你正在试图解决一个你还没有意识到的问题。那么:你到底想用这个来实现什么?也许他把“一次”和“同时”混淆了?@Franzgleichann我想了一下,是否有可能实现这样的场景…我想了读写锁、信号量、生产者-消费者,但找不到解决方法…使用这种方法,正在再次多次调用该方法。我需要它只被调用一次,并与其他线程共享它的结果。。。I@downvoter否决投票的理由是什么?如果我知道如何改进我的答案,那将非常有帮助!谢谢您的解决方案很好,但它同样会导致计算器方法被多次调用。看到我的更新问题,我已经试图澄清它多一点使用这种方法,该方法正在被调用多次。我需要它只被调用一次,并与其他线程共享它的结果。。。I@downvoter否决投票的理由是什么?如果我知道如何改进我的答案,那将非常有帮助!谢谢您的解决方案很好,但它同样会导致计算器方法被多次调用。这正是我的意思和需要。谢谢这正是我的意思和需要。谢谢