TGViewer
Библиотека шарписта | C#, F#, .NET, ASP.NET Библиотека шарписта | C#, F#, .NET, ASP.NET @csharpproglib · 21.7K subscribers
Post #6667 4.14K
⚙️ Передаём данные между потоками

В C# есть несколько способов передать данные из одного потока в другой. Выбор зависит от требований к производительности, удобству и безопасности. Несколько распространенных вариантов:

1️⃣ Использование BlockingCollection<T>

Это потокобезопасная коллекция, позволяющая передавать данные от одного потока к другому.
var collection = new BlockingCollection<int>();

// Поток-поставщик (Producer)
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
collection.Add(i);
Console.WriteLine($"Производитель: добавил {i}");
Thread.Sleep(500);
}
collection.CompleteAdding();
});

// Поток-потребитель (Consumer)
Task.Run(() =>
{
foreach (var item in collection.GetConsumingEnumerable())
{
Console.WriteLine($"Потребитель: получил {item}");
}
}).Wait();


2️⃣ Использование TaskCompletionSource<T>

Когда нужно передать значение между потоками в будущем.

var tcs = new TaskCompletionSource<int>();

// Поток-поставщик
Task.Run(() =>
{
Thread.Sleep(2000);
tcs.SetResult(42);
});

// Поток-потребитель
int result = await tcs.Task;
Console.WriteLine($"Получено: {result}");


3️⃣ Использование ConcurrentQueue<T>

Если нужно неблокирующее хранилище данных.

var queue = new ConcurrentQueue<int>();

// Поток-поставщик
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
queue.Enqueue(i);
Console.WriteLine($"Добавлено {i}");
Thread.Sleep(500);
}
});

// Поток-потребитель
Task.Run(() =>
{
while (true)
{
if (queue.TryDequeue(out int item))
{
Console.WriteLine($"Получено {item}");
}
Thread.Sleep(100);
}
}).Wait();


4️⃣ Использование Channel<T> (System.Threading.Channels)

Альтернативный подход к BlockingCollection<T>

var channel = Channel.CreateUnbounded<int>();

// Поток-поставщик
_ = Task.Run(async () =>
{
for (int i = 0; i < 10; i++)
{
await channel.Writer.WriteAsync(i);
Console.WriteLine($"Производитель: {i}");
await Task.Delay(500);
}
channel.Writer.Complete();
});

// Поток-потребитель
await foreach (var item in channel.Reader.ReadAllAsync())
{
Console.WriteLine($"Потребитель: {item}");
}


💬 Какой вариант используете в проде?

📍 Навигация: Вакансии • Задачи • Собесы

🐸Библиотека шарписта

#лучшее_из_библиотеки_2025
  • 🤩 7
  • ❤ 5
More from @csharpproglib
  1. Sep 28, 2026👨‍💻 Не показывайте технические ошибки пользователям Когда приложение падает с необработа…
  2. Sep 26, 2026📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека шарписта #garbage_collector
  3. Sep 25, 2026🔐 NuGet: Microsoft меняет сертификат подписи С 23 сентября Microsoft использует новый сер…
  4. Sep 24, 2026🤩 Как поймать зависший .NET-сервис Приложение начинает тормозить, запросы зависают, а в л…
  5. Sep 23, 2026⚙️ yield return не бесплатный Итераторы выглядят просто, но работают иначе: IEnumerable<in…
  6. Sep 22, 2026💡 Replace, Regex или StringBuilder? Для замены текста в C# есть несколько инструментов. И…
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 →