(0) exportieren Drucken
Alle erweitern
Dieser Artikel wurde maschinell übersetzt. Bewegen Sie den Mauszeiger über die Sätze im Artikel, um den Originaltext anzuzeigen. Weitere Informationen
Übersetzung
Original

lock-Anweisung (C#-Referenz)

Das lock-Schlüsselwort kennzeichnet einen Anweisungsblock als kritischen Abschnitt, indem die Sperre für gegenseitigen Ausschluss eines bestimmten Objekts ermittelt, eine Anweisung ausgeführt und die Sperre wieder aufgehoben wird. Das folgende Beispiel enthält eine lock-Anweisung.


    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 (C# und Visual Basic).

Mit dem lock-Schlüsselwort wird sichergestellt, dass ein Thread nicht auf einen kritischen Abschnitt des Codes zugreift, während ein anderer Thread mit diesem Codeabschnitt befasst ist. Wenn ein anderer Thread versucht, auf gesperrten Code zuzugreifen, wartet er bis zur Freigabe des Objekts (Blockierung).

Im Abschnitt Threading (C# und Visual Basic) wird das Threading beschrieben.

Das lock-Schlüsselwort ruft Enter am Anfang des Blocks und Exit am Ende des Blocks auf. ThreadInterruptedException wird ausgelöst, wenn Interrupt einen Thread unterbrochen wird, der wartet, eine lock-Anweisung einzugeben.

Vermeiden Sie es grundsätzlich, einen public-Typ zu sperren oder Instanzen, die nicht durch Ihren Code gesteuert werden. Die allgemeinen Konstrukte lock (this), lock (typeof (MyType)) und lock ("myLock") verstoßen gegen diese Richtlinie:

  • lock (this) ist problematisch, wenn auf die Instanz öffentlich zugegriffen werden kann.

  • lock (typeof (MyType)) ist problematisch, wenn MyType öffentlich zugreifbar ist.

  • lock("myLock") ist problematisch, weil jeder andere Code in diesem Prozess, der dieselbe Zeichenfolge verwendet, von derselben Sperre betroffen ist.

Es wird empfohlen, ein private-Objekt zu definieren, das gesperrt werden soll, oder eine private static-Objektvariable, um Daten zu schützen, die alle Instanzen gemeinsam nutzen.

Sie können das Sie erwarten(await)-Schlüsselwort nicht im Rumpf einer lock-Anweisung verwenden.

Im folgenden Beispiel wird eine einfache Verwendung von Threads ohne Sperren in C# dargestellt:


    //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



Im folgenden Beispiel werden Threads und lock verwendet. Solange die lock-Anweisung vorhanden ist, stellt der Anweisungsblock einen kritischen Abschnitt dar, und balance wird nie zu einer negativen Zahl.


    // 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();
            }
        }
    }



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

Community-Beiträge

HINZUFÜGEN
Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?
Anzeigen:
© 2014 Microsoft