c# - 线程间共享方法
问题描述
我有一个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
也不是我想要的,因为在这种情况下,计算器再次被多次调用......
解决方案
看来你需要这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>
以线程安全的方式初始化实例。
推荐阅读
- python - ModuleNotFoundError:没有名为“_future_”的模块
- javascript - 如何在 selenium Safari Capabilities 中设置默认下载目录?
- node.js - 如何更改端口号并永远运行服务?
- html - CSS:内容重叠页脚
- c++ - 编译 c++ 文件后无法运行 .exe 文件
- c++ - static_cast 是否创建了新的子对象?
- ios - 多个动画在 SwiftUI 中无法按预期工作
- java - 在 SBA-UI -Environment 中刷新 Context SBA-Client 后,显示状态为 DOWN
- r - R:根据矩阵值删除向量元素
- java - 在 Windows 上为 Vim 清理 javac 输出,可能通过 Unix (Cygwin) 工具