【发布时间】:2013-05-09 13:12:56
【问题描述】:
(注意:我已经问过这个问题,但答案是针对 Java 的,所以我对 C# 和 .NET 框架提出了同样的问题。它不是重复的。)
我使用这种模式已经有一段时间了,但直到最近我才开始认为这样做可能不太好。基本上,我使用了这种模式的一些变体:
public class SampleAsync
{
public SampleAsync() { }
private bool completed;
public void Start()
{
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => {
//... do something on a different thread
completed = true;
};
worker.RunWorkerAsync();
}
public void Update()
{
if (!completed) return;
//... do something else
}
}
*用户负责确保Start 只被调用一次。随时随地调用Update。
我一直认为这在 C#/.NET 框架中是线程安全的,因为即使没有严格同步,我也只将 completed 设置为 true。一旦观察到它是true,它就不会重置为false。它在构造函数中被初始化为 false,根据定义,它是线程安全的(除非你在其中做了一些愚蠢的事情)。那么,以这种方式使用不可重置标志是线程安全的吗? (如果是这样,它甚至会提供任何性能优势吗?)
谢谢
【问题讨论】:
-
在 C# 和 Java 中?否则它是线程安全的吗?
-
“一旦它被观察到是真实的”是如果你不使用
volatile可能永远不会发生的位。 -
为什么不直接使用后台worker的
IsBusy属性来判断是否完成呢?我想他们确保可以从任何线程安全地访问它。 -
@Servy 我并没有真正询问
BackgroundWorker- 这只是为了演示。关键是completed设置在不同的线程中,不一定在线程生命周期结束时。 -
@aboveyou00 我的意思是,这就是为什么存在诸如
BackgroundWorker之类的类的原因;帮助管理来自最常见用例的线程之间的同步。你应该学会利用它。
标签: c# .net asynchronous thread-safety