lock-Anweisung (C#-Referenz)lock Statement (C# Reference)

Das Schlüsselwort lock kennzeichnet einen Anweisungsblock als kritischen Abschnitt, indem es die sich gegenseitig ausschließende Sperre für ein gegebenes Objekt abruft, eine Anweisung ausführt und anschließend die Sperre aufhebt.The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock. Das folgende Beispiel enthält eine lock-Anweisung.The following example includes a lock statement.

class Account  
{  
    decimal balance;  
    private Object thisLock = new Object();  

    public void Withdraw(decimal amount)  
    {  
        lock (thisLock)  
        {  
            if (amount > balance)  
            {  
                throw new Exception("Insufficient funds");  
            }  
            balance -= amount;  
        }  
    }  
}  

Weitere Informationen finden Sie unter Threadsynchronisierung.For more information, see Thread Synchronization.

HinweiseRemarks

Das Schlüsselwort lock stellt sicher, dass ein Thread keinen kritischen Abschnitt eines Codes betritt, während ein anderer Thread in diesem Abschnitt ist.The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. Wenn ein anderer Thread versucht, auf einen gesperrten Code zuzugreifen, wartet er, sperrt, bis das Objekt freigegeben wird.If another thread tries to enter a locked code, it will wait, block, until the object is released.

Der Abschnitt Threading wird das Threading behandeln.The section Threading discusses threading.

Das lock-Schlüsselwort ruft am Anfang des Blocks Enter und am Ende des Blocks Exit auf.The lock keyword calls Enter at the start of the block and Exit at the end of the block. Ein ThreadInterruptedException wird ausgelöst, wenn Interrupt einen Thread unterbricht, der darauf wartet eine lock-Anweisung einzugeben.A ThreadInterruptedException is thrown if Interrupt interrupts a thread that is waiting to enter a lock statement.

Vermeiden Sie generell das Sperren eines public-Typs oder von Instanzen außerhalb der Kontrolle Ihres Codes.In general, avoid locking on a public type, or instances beyond your code's control. Die gemeinsamen Konstrukte lock (this), lock (typeof (MyType)) und lock ("myLock") verstoßen gegen diese Richtlinie:The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) ist ein Problem, wenn auf die Instanz öffentlich zugegriffen werden kann.lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) ist problematisch, wenn auf MyType öffentlich zugegriffen werden.lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock("myLock") ist problematisch, weil jeder andere Code in diesem Prozess, der die selbe Zeichenfolge verwendet, die gleiche Sperre teilt.lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.

Eine bewährte Methode ist es, ein private-Objekt zum Sperren, oder eine private static-Objektvariable zu definieren, die Daten schützt, die in allen Instanzen häufig vorkommen.Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

Sie können das Schlüsselwort await nicht im Text einer lock-Anweisung verwenden.You can't use the await keyword in the body of a lock statement.

BeispielExample

Im folgenden Beispiel wird eine einfache Verwendung von Threads ohne das Sperren in C# gezeigt.The following sample shows a simple use of threads without locking in C#.

//using System.Threading;

class ThreadTest
{
    public void RunMe()
    {
        Console.WriteLine("RunMe called");
    }

    static void Main()
    {
        ThreadTest b = new ThreadTest();
        Thread t = new Thread(b.RunMe);
        t.Start();
    }
}
// Output: RunMe called

BeispielExample

Im folgenden Beispiel werden Threads und lock verwendet.The following sample uses threads and lock. Solange die lock-Anweisung vorhanden ist, ist der Anweisungsblock ein kritischer Abschnitt, und balance wird nie eine negative Zahl werden.As long as the lock statement is present, the statement block is a critical section and balance will never become a negative number.

// using System.Threading;

class Account
{
    private Object thisLock = new Object();
    int balance;

    Random r = new Random();

    public Account(int initial)
    {
        balance = initial;
    }

    int Withdraw(int amount)
    {

        // This condition never is true unless the lock statement
        // is commented out.
        if (balance < 0)
        {
            throw new Exception("Negative Balance");
        }

        // Comment out the next line to see the effect of leaving out 
        // the lock keyword.
        lock (thisLock)
        {
            if (balance >= amount)
            {
                Console.WriteLine("Balance before Withdrawal :  " + balance);
                Console.WriteLine("Amount to Withdraw        : -" + amount);
                balance = balance - amount;
                Console.WriteLine("Balance after Withdrawal  :  " + balance);
                return amount;
            }
            else
            {
                return 0; // transaction rejected
            }
        }
    }

    public void DoTransactions()
    {
        for (int i = 0; i < 100; i++)
        {
            Withdraw(r.Next(1, 100));
        }
    }
}

class Test
{
    static void Main()
    {
        Thread[] threads = new Thread[10];
        Account acc = new Account(1000);
        for (int i = 0; i < 10; i++)
        {
            Thread t = new Thread(new ThreadStart(acc.DoTransactions));
            threads[i] = t;
        }
        for (int i = 0; i < 10; i++)
        {
            threads[i].Start();
        }
        
        //block main thread until all other threads have ran to completion.
        foreach (var t in threads)
            t.Join();
    }
}

C#-ProgrammiersprachenspezifikationC# Language Specification

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auchSee Also

MethodImplAttributes
Mutex
C#-ReferenzC# Reference
C#-ProgrammierhandbuchC# Programming Guide
ThreadingThreading
C#-SchlüsselwörterC# Keywords
AnweisungsschlüsselwörterStatement Keywords
Monitor
Interlocked-VorgängeInterlocked Operations
AutoResetEventAutoResetEvent
ThreadsynchronisierungThread Synchronization