ICollection.SyncRoot Свойство

Определение

Получает объект, с помощью которого можно синхронизировать доступ к коллекции ICollection.

public:
 property System::Object ^ SyncRoot { System::Object ^ get(); };
public object SyncRoot { get; }
member this.SyncRoot : obj
Public ReadOnly Property SyncRoot As Object

Значение свойства

Объект, который может быть использован для синхронизации доступа к коллекции ICollection.

Комментарии

Для коллекций, хранилище которых не является общедоступным, ожидаемая реализация возвращает текущий экземпляр. Обратите внимание, что указателя на текущий экземпляр может быть недостаточно для коллекций, которые обтекают другие коллекции; они должны возвращать свойство базовой SyncRoot коллекции.

Большинство классов коллекций в пространстве имен System.Collections также реализуют метод Synchronized, который обеспечивает создание синхронизированной оболочки для коллекции. Однако производные классы могут предоставлять собственную синхронизированную версию коллекции с помощью свойства SyncRoot. Синхронизированный код должен выполнять операции над свойством SyncRoot коллекции, но не над самой коллекцией. Это обеспечивает правильную работу коллекций, являющихся производными других объектов. В частности, это обеспечивает правильную синхронизацию с другими потоками, которые могут одновременно вносить изменения в экземпляр коллекции.

При отсутствии Synchronized метода в коллекции ожидаемое использование для SyncRoot выглядит следующим образом:

ICollection^ myCollection = someCollection;
bool lockTaken = false;
try
{
    Monitor::Enter(myCollection->SyncRoot, lockTaken);
    // Some operation on the collection, which is now thread safe.
}
finally
{
    if (lockTaken)
    {
        Monitor::Exit(myCollection->SyncRoot);
    }
}
ICollection myCollection = someCollection;
lock(myCollection.SyncRoot)
{
    // Some operation on the collection, which is now thread safe.
}
Dim myCollection As ICollection = someCollection
SyncLock myCollection.SyncRoot
    ' Some operation on the collection, which is now thread safe.
End SyncLock

Перечисление коллекции не является потокобезопасной процедурой. Даже если коллекция синхронизирована, другие потоки могут ее изменить, что приведет к тому, что перечислитель создаст исключение. Для обеспечения потокобезопасности при перечислении можно либо заблокировать коллекцию на все время перечисления, либо перехватывать исключения, возникающие в результате изменений, внесенных другими потоками.

В следующем примере кода показано, как заблокировать коллекцию SyncRoot с помощью свойства во время всего перечисления.

ICollection^ myCollection = someCollection;
bool lockTaken = false;
try
{
    Monitor::Enter(myCollection->SyncRoot, lockTaken);
    for each (Object^ item in myCollection);
    {
        // Insert your code here.
    }
}
finally
{
    if (lockTaken)
    {
        Monitor::Exit(myCollection->SyncRoot);
    }
}
ICollection myCollection = someCollection;
lock(myCollection.SyncRoot)
{
    foreach (object item in myCollection)
    {
        // Insert your code here.
    }
}
Dim myCollection As ICollection = someCollection
SyncLock myCollection.SyncRoot
    For Each item In myCollection
        ' Insert your code here.
    Next item
End SyncLock

Применяется к

См. также раздел