TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #1721 1.51K
День 1390. #ЗаметкиНаПолях #AsyncTips
Блокировки с async

Задача
Имеются общие данные. Требуется обеспечить безопасное чтение и запись этих данных из разных блоков кода, внутри которых может использоваться await.

Решение
Тип SemaphoreSlim был обновлён в .NET 4.5 для обеспечения совместимости с async. Пример использования:
class MyClass
{
private int _value;
// Блокировка защищает поле _value
private readonly SemaphoreSlim
semaphore = new SemaphoreSlim(1);

public async Task IncAsync(string name)
{
await semaphore.WaitAsync();
try
{
int oldValue = _value;
await Task.Delay(1000 * oldValue);
_value = oldValue + 1;

Console.WriteLine($"{name}: {_value}");
}
finally
{
semaphore.Release();
}
}
}

Тестовый вариант использования класса:
var cls = new MyClass();

for (int i = 1; i <= 5; i++)
{
int count = i;
Thread t = new(
async () =>
await cls.IncAsync("Поток " + count)
);
t.Start();
}
Console.ReadLine();

Этот код будет выводить одну за другой строки с постоянно увеличивающейся задержкой между ними:
Поток 4: 1
Поток 3: 2
Поток 2: 3
Поток 5: 4
Поток 1: 5

Заметьте, что SemaphoreSlim принимает в качестве параметра конструктора количество потоков, которые одновременно могут получить доступ к блокировке. В данном случае мы задали 1.

В этой ситуации действуют рекомендации из предыдущего совета:
Экземпляры блокировок должны быть приватными; т.е. не должны быть доступными за пределами класса. Обязательно чётко документируйте (и тщательно продумывайте), что именно защищает экземпляр блокировки. Сведите к минимуму объём кода, выполняемого при удержании блокировки. В частности, не вызывайте произвольный код, включая выдачу событий, вызов виртуальных методов и вызов делегатов.

Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 12.
  • 👍 23
More from @netdeveloperdiary
  1. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  2. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  3. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  4. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  5. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  6. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →