以下代码块预先在C#中加载对象。
public bool IsModelLoaded { get; set; }
public override MyObject Load()
{
if (!IsModelLoaded)
{
Model = MyService.LoadMyObject(Model);
IsModelLoaded = true;
}
return Model;
}
我的目的是只运行一次这个块,因此只加载一次Model。 不过,这个代码块从2个不同的线程运行两次..
如何确保此块只运行一次? (在多线程上)。
谢谢。
答案 0 :(得分:3)
最简单的是添加
[MethodImpl(MethodImplOptions.Synchronized)]
public override MyObject Load()
{
//snip
}
但请注意,这会锁定整个对象,而不仅仅是方法。不是很好的练习。
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions.aspx
同步
指定该方法一次只能由一个线程执行。静态方法锁定类型,而实例方法锁定实例。只有一个线程可以在任何实例函数中执行,并且只有一个线程可以在任何类的静态函数中执行。
答案 1 :(得分:2)
private readonly Lazy<MyObject> myObject;
public MyClass()
{
myObject = new Lazy<MyObject>(() =>
{
return MyService.LoadMyObject();
}, LazyThreadSafetyMode.ExecutionAndPublication);
}
public bool IsModelLoaded
{
get { return myObject.IsValueCreated; }
}
public override MyObject Load()
{
return myObject.Value;
}
答案 2 :(得分:1)
我正在尝试实施singleton
模式。但是你的版本不是线程安全的。在此处阅读更多内容:http://www.dofactory.com/Patterns/PatternSingleton.aspx。尝试使用此实现:
public sealed class Singleton
{
static Singleton instance=null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
答案 3 :(得分:1)
Action myCodeBlock = ()=>
{
//do your job
//...
myCodeBlock = ()=>{};
}
一旦调用myCodeBlock()
,它将被不执行任何操作的方法重写。您仍然需要确保安全地调用此metod - 使用lock
或其他任何内容。
答案 4 :(得分:1)
答案 5 :(得分:1)
如果你想编写线程安全代码并确保该块只运行一次,你可以像这样写:
private System.Object lockThis = new System.Object();
public override MyObject Load()
{
lock (lockThis) {
if (!IsModelLoaded)
{
Model = MyService.LoadMyObject(Model);
IsModelLoaded = true;
}
}
return Model;
}
答案 6 :(得分:0)
创建一个静态对象(如布尔值),通过将代码置于if语句中来确定代码是否已运行:)
编辑:我不确定这是否是线程安全的,所以它可能不适合你。