Для какого конкретного случая использования введен новый System.Threading.Lock в .Net 9?C#

Место общения программистов C#
Ответить
Anonymous
 Для какого конкретного случая использования введен новый System.Threading.Lock в .Net 9?

Сообщение Anonymous »

Я пытаюсь разобраться в новом объекте System.Threading.Lock в C#9.
Раньше я использовал старый добрый lock(object) чтобы предотвратить доступ нескольких потоков к одной и той же части кода, например:

Код: Выделить всё

public class LazyLoadedItem
{
}

private LazyLoadedItem _item = null;

private readonly object MyLock = new object();

public LazyLoadedItem GetItem
{
get
{
{
if (_item != null)
return _item;

lock (MyLock)
{
// Serve the queue of threads that passed the first check when the floodgates opened...
if (_item != null)
return _item;

_item = new LazyLoadedItem(); // get from Database/FileSystem/Web
}

return _item;
}
}
}

public void ClearCache()
{
_item = null;
}
Это сработало хорошо, и я даже мог безопасно выполнять рекурсивные действия в том же потоке, используя эту блокировку, поскольку блокировка была «привязанной к потоку».
Однако... с наступлением эпохи await async блокировать таким образом было уже небезопасно, так как поток будет повторно использоваться, как только ему нужно будет дождаться базы данных/сети/файловой системы или чего-то еще. С тех пор я бы принял новый шаблон, используя SemaphoorSlim, чтобы обеспечить безопасную блокировку, например:

Код: Выделить всё

private readonly SemaphoreSlim MyLock = new SemaphoreSlim(1, 1);

public async Task GetItem(CancellationToken requestCancelled)
{
if (_item != null)
return _item;

await MyLock.WaitAsync(requestCancelled); // throws exception when cancelled
try
{
// Serve the queue of threads that passed the first check when the floodgates opened...
if (_item != null)
return _item;

_item = await GetLazyLoadedItem().ConfigureAwait(false); // get from Database/FileSystem/Web
// note that we may be continuing on a different thread here!
}
finally
{
MyLock.Release();
}

return _item;
}
Немного не по теме, но безопасно ли ждать MyLock.WaitAsync(requestCancelled).ConfigureAwait(false);? Я никогда не осмеливался использовать ConfigurationAwait(false) для этого конкретного вызова.
В любом случае, мой вопрос о новом System.Threading.Lock заключается в том, где он подходит в? Это «асинхронно безопасно»?
Если нет, то я предполагаю, что его использование ограничено кодом, который никогда ничего не ожидает (например, вычисления кэширования, такие как общее количество * вес некоторой коллекции), что, на мой взгляд, сводит его вариант использования до такой малой величины, что внедрение в C#9 вряд ли оправдано. Единственное потенциальное применение, которое я могу придумать, — это кэширование отражения следующим образом:

Код: Выделить всё

private static Dictionary _props = null;

private static readonly System.Threading.Lock _myLock = new System.Threading.Lock();

public Dictionary Props
{
get
{
if (_props != null)
return _props;

lock (_myLock)
{
// Serve the queue of threads that passed the first check when the floodgates opened...
if (_props != null)
return _props;

_props = this.GetType().GetProperties().ToDictionary(p => p.Name);
}

return _props;
}
}
Это может быть полезно для контейнеров сериализации или внедрения (пока GetProperties() и ToDictionary() не являются асинхронными), но поскольку блокировка будет только использоваться в течение части времени существования процесса во время запуска или при первом использовании, весь смысл оптимизации теряется.
Так почему же был введен новый System.Threading.Lock ? Я полагаю, что в целом подавляющее большинство кода должно использовать SemaphoreSlim? Что мне не хватает?

Подробнее здесь: https://stackoverflow.com/questions/791 ... -9-introdu
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»