Entwurfsrichtlinien für das Threading

Die folgenden Regeln dienen als Richtlinie für die Implementierung von Threading:

  • Vermeiden Sie die Bereitstellung von statischen Methoden, die den statischen Status verändern. Bei den üblichen Serverszenarios wird der statische Status in mehreren Anforderungen gemeinsam genutzt, d. h. mehrere Threads können diesen Code gleichzeitig ausführen. Dadurch werden Threadingfehler möglich. Verwenden Sie u. U. ein Entwurfsschema, bei dem Daten in Instanzen eingekapselt werden, die nicht in mehreren Anforderungen gemeinsam genutzt werden.

  • Der statische Status muss threadsicher sein.

  • Der Instanzenstatus muss nicht threadsicher sein. Klassenbibliotheken sollten in der Standardeinstellung nicht threadsicher sein. Durch Hinzufügen von Sperren, um threadsicheren Code zu erstellen, wird die Leistung beeinträchtigt, die Sperrenkonflikte werden erhöht, und es ensteht die Gefahr von Deadlockfehlern. Bei den gängigen Anwendungsmodellen führt immer nur ein Thread Benutzercode aus, wodurch die Notwendigkeit der Threadsicherheit reduziert wird. Aus diesem Grund sind .NET Framework-Klassenbibliotheken in der Standardeinstellung nicht threadsicher. Stellen Sie in Fällen, in denen Sie eine threadsichere Version zur Verfügung stellen möchten, eine Synchronized-Methode bereit, die eine threadsichere Instanz eines Typs zurückgibt. Ein Beispiel finden Sie unter der System.Collections.ArrayList.Synchronized-Methode und der System.Collections.ArrayList.IsSynchronized-Methode.

  • Berücksichtigen Sie beim Entwerfen der Bibliothek die Belastungen im Zusammenhang mit der Ausführung in einem Serverszenario. Vermeiden Sie, wann immer möglich, die Verwendung von Sperren.

  • Achten Sie auf Methodenaufrufe in gesperrten Abschnitten. Deadlocks können auftreten, wenn eine statische Methode in einer Klasse A statische Methoden in Klasse B aufruft und umgekehrt. Wenn A und B ihre statischen Methoden synchronisieren, führt dies zu einem Deadlock. Diesen Deadlock können Sie u. U. nur unter hoher Threadauslastung feststellen.

  • Zu Leistungseinbußen kann es kommen, wenn eine statische Methode in Klasse A eine statische Methode in Klasse A aufruft. Wenn diese Methoden nicht korrekt in Faktoren zerlegt werden, wird die Leistung beeinträchtigt, da viel redundante Synchronisierung anfällt. Eine übermäßige Verwendung von feinkörniger Synchronisierung kann sich negativ auf die Leistung auswirken. Sie kann außerdem die Skalierbarkeit erheblich beeinträchtigen.

  • Bedenken Sie Probleme mit der lock-Anweisung (in Visual Basic SyncLock). Es ist natürlich verlockend, die lock-Anweisung zum Beheben aller Threadingprobleme zu verwenden. Die System.Threading.Interlocked-Klasse ist jedoch für Aktualisierungen, die atomar sein müssen, die überlegene Methode. Sie führt ein einzelnes lock-Präfix aus, wenn kein Konflikt vorliegt. Achten Sie bei der Codeüberprüfung auf Instanzen wie die im folgenden Beispiel gezeigte.

    SyncLock Me
       myField += 1
    End SyncLock
    [C#]
    lock(this) 
    {
       myField++;
    }
    

    Wenn Sie das vorangegangene Beispiel duch das folgende ersetzen, wird die Leistung gesteigert.

    System.Threading.Interlocked.Increment(myField)
    [C#]
    System.Threading.Interlocked.Increment(myField);
    

    Eine weitere Möglichkeit besteht darin, eine Objekttypenvariable nur dann zu aktualisieren, wenn diese null (in Visual Basic Nothing) ist. Sie können mit dem folgenden Code die Variable aktualisieren und den Code threadsicher machen.

    If x Is Nothing Then
       SyncLock Me
          If x Is Nothing Then
             x = y
          End If
       End SyncLock
    End If
    [C#]
    if (x == null)
    {
       lock (this)
       {
          if (x == null)
          {
             x = y;
          }
       }
    }
    

    Sie können die im vorangegangenen Beispiel erzielte Leistung steigern, indem Sie es durch folgenden Code ersetzen.

    System.Threading.Interlocked.CompareExchange(x, y, Nothing)
    [C#]
    System.Threading.Interlocked.CompareExchange(ref x, y, null);
    
  • Vermeiden Sie, falls möglich, die Notwendigkeit der Synchronisierung. Dies gilt vor allem für Pfade mit hohem Datenverkehrsaufkommen. In manchen Fällen kann der Algorithmus so korrigiert werden, dass er Racebedingungen toleriert, anstatt sie zu beseitigen.

Siehe auch

Entwurfsrichtlinien für die Entwicklung von Klassenbibliotheken | Sprachänderungen in Visual Basic | System.Threading-Namespace