8

次のコードブロックは、C#でオブジェクトの読み込みを実行します。

public bool IsModelLoaded { get; set; }
public override MyObject Load()
{
    if (!IsModelLoaded)
    {
        Model = MyService.LoadMyObject(Model);
        IsModelLoaded = true;
    }
    return Model;
}

私の意図は、このブロックを1回だけ実行することです。したがって、ロードはModel1回だけです。それにもかかわらず、このコードブロックは2つの異なるスレッドから2回実行されます。

このブロックが1回だけ実行されるようにするにはどうすればよいですか?(複数のスレッドで)。

4

7 に答える 7

4

Lazy <T>クラスを使用します:

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;
}
于 2012-10-26T14:06:37.483 に答える
2

最も簡単なのは追加することです

[MethodImpl(MethodImplOptions.Synchronized)]
public override MyObject Load()
{
   //snip
}

ただし、これにより、メソッドだけでなくオブジェクト全体がロックされることに注意してください。あまり良い習慣ではありません。

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions.aspx

同期

メソッドを一度に1つのスレッドでのみ実行できることを指定します。静的メソッドは型をロックしますが、インスタンスメソッドはインスタンスをロックします。インスタンス関数のいずれかで実行できるスレッドは1つだけであり、クラスの静的関数のいずれかで実行できるスレッドは1つだけです。

于 2012-10-26T14:06:36.253 に答える
2

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;
            }
        }
    }
}
于 2012-10-26T14:06:46.190 に答える
2

スレッドセーフなコードを記述し、ブロックが1回だけ実行されるようにする場合は、次のように記述できます。

private System.Object lockThis = new System.Object(); 
public override MyObject Load()
{
    lock (lockThis) {
        if (!IsModelLoaded)
        {
            Model = MyService.LoadMyObject(Model);
            IsModelLoaded = true;
        }
    }
    return Model;
}
于 2012-10-26T14:08:59.827 に答える
1
Action myCodeBlock = ()=>
{
  //do your job
  //...
  myCodeBlock = ()=>{};
}

一度呼び出すとmyCodeBlock()、何もしないメソッドで書き換えられます。この方法が安全に呼び出されることを確認する必要があります-使用するlockかどうか。

于 2012-10-26T14:07:12.943 に答える
1

ロックステートメントを使用できます(C#リファレンス)

于 2012-10-26T14:07:14.397 に答える
-1

ifステートメントにコードを配置することでコードが実行されたかどうかを判断する静的オブジェクト(ブール値など)を作成します:)

編集:これがスレッドセーフかどうかはわかりませんので、解決策ではない可能性があります。

于 2012-10-26T14:06:08.367 に答える