【发布时间】:2010-02-11 01:06:40
【问题描述】:
免责声明:我的帖子显然总是很冗长。如果您碰巧知道标题问题的答案,请随意回答,而无需阅读下面我的扩展讨论。
System.Threading.Interlocked 类提供了一些非常有用的方法来帮助编写线程安全代码。更复杂的方法之一是CompareExchange,可用于计算可能从多个线程更新的运行总数。
由于CompareExchange的使用有点棘手,我认为为其提供一些辅助方法是一个相当常识的想法:
// code mangled so as not to require horizontal scrolling
// (on my monitor, anyway)
public static double Aggregate
(ref double value, Func<double, double> aggregator) {
double initial, aggregated;
do {
initial = value;
aggregated = aggregator(initial);
} while (
initial != Interlocked.CompareExchange(ref value, aggregated, initial)
);
return aggregated;
}
public static double Increase(ref double value, double amount) {
return Aggregate(ref value, delegate(double d) { return d + amount; });
}
public static double Decrease(ref double value, double amount) {
return Aggregate(ref value, delegate(double d) { return d - amount; });
}
现在,也许我只是对普通的快乐感到内疚(我承认,这通常是真的);但是对我来说将上述方法提供的功能限制为仅double 值确实很愚蠢(或者,更准确地说,我必须为每种类型编写上述方法的重载版本我要支持)。为什么我不能这样做?
// the code mangling continues...
public static T Aggregate<T>
(ref T value, Func<T, T> aggregator) where T : IEquatable<T> {
T initial, aggregated;
do {
initial = value;
aggregated = aggregator(initial);
} while (
!initial.Equals(
Interlocked.CompareExchange<T>(ref value, aggregated, initial)
)
);
}
我不能这样做,因为Interlocked.CompareExchange<T> 显然有where T : class 约束,并且我不明白为什么。我的意思是,也许这是因为CompareExchange 已经有接受Int32、Int64、Double 等的重载;但这似乎不是一个好的理由。例如,在我的例子中,能够使用Aggregate<T> 方法来执行广泛的原子计算会非常方便。
【问题讨论】:
标签: c# .net multithreading interlocked