C# Ready | Unity
9.71K subscribers
1.34K photos
79 videos
660 links
Авторский канал по разработке на C# и Unity.
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!

Автор: @energy_c

РКН: https://clck.ru/3SBaT3
Download Telegram
👩‍💻 Сегодня рассмотрим Channel<T> — безопасная асинхронная очередь задач в .NET

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

Что важно знать:

Работает без ручных блокировок и сложных синхронных вызовов.

Позволяет автоматически замедлять отправку при перегрузке памяти.

Обеспечивает плавную передачу данных между параллельными задачами.


Так вы получаете готовый «из коробки» механизм асинхронной очереди с естественным управлением нагрузкой без лишнего кода.

C# Ready | #гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥95👍3🤝1
2🔥2👍1🤝1
Понятный разбор того, как на самом деле работает async/await в C#!

В этой статье:
• Чем асинхронность отличается от запуска работы в отдельном потоке
• Когда await освобождает поток, а когда выполнение продолжается синхронно
• Как компилятор превращает асинхронный метод в машину состояний

Продолжай читать на Habr!


➡️ C# Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍74🔥3
Почему yield return в C# выполняется не сразу?

Метод с yield выглядит как обычный метод:
IEnumerable<int> GetNumbers()
{
Console.WriteLine("start");
yield return 1;
yield return 2;
}


Но при вызове код внутри ещё не выполняется:
var numbers = GetNumbers();

Console.WriteLine("created");


В консоли сначала будет:
created


А строка start появится только тогда, когда коллекцию начнут реально перебирать:
foreach (var number in numbers)
{
Console.WriteLine(number);
}


И вот тогда выполнение пойдёт пошагово:
start
1
2


Это важно помнить, если внутри iterator-метода есть чтение файла, запрос к базе, логирование или любая другая побочная логика.

Например, такой код может выполнить запрос не там, где кажется:
var users = LoadUsers();

DoSomething();

foreach (var user in users)
{
Console.WriteLine(user.Name);
}


LoadUsers() может начать работу только на foreach, а не на первой строке.

Если нужно зафиксировать результат сразу, материализуй последовательность:
var users = LoadUsers().ToList();


yield return создаёт ленивую последовательность. Код внутри запускается при перечислении, а не при вызове метода.

➡️ C# Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍3🔥2
Простая и популярная статья о создании Telegram-бота на C#!

В этой статье:
• Как создать бота через BotFather и подключить его к проекту
• Как принимать сообщения пользователя и отправлять ответы
• Как собрать базу, от которой уже можно развивать своего бота дальше

Продолжай читать на Habr!


➡️ C# Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍4🔥3
Шпаргалка по недооценённым LINQ-методам в C#!

Например, SequenceEqual() помогает сравнить две последовательности по элементам, ToLookup() создаёт удобную группировку для быстрого доступа по ключу, а GroupJoin() полезен, когда нужно связать две коллекции и получить вложенный результат.

На картинке 5 LINQ-методов с короткими примерами кода: SequenceEqual, Aggregate, GroupJoin, ToLookup и Intersect.

Сохрани, чтобы не потерять!

➡️ C# Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍7🔥6
Опа, тут бывший сеньор одного из IT-отделов Яндекса Игорь Никитин выкатил целый канал про Python — и это лучшее, что есть в рунете по теме.

Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.

Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
👎9
Собираем простую очередь фоновых задач!

Иногда в приложении нужно отложить работу: отправить email, записать аудит, обработать файл или выполнить тяжёлую операцию после ответа пользователю.

Для этого можно собрать небольшую очередь на Channel<T>.

Сначала заведём интерфейс:
public interface ITaskQueue
{
ValueTask EnqueueAsync(Func<CancellationToken, Task> job);
IAsyncEnumerable<Func<CancellationToken, Task>> ReadAllAsync(
CancellationToken token
);
}


Реализация будет хранить задачи внутри Channel:
using System.Threading.Channels;

public sealed class TaskQueue : ITaskQueue
{
private readonly Channel<Func<CancellationToken, Task>> _channel =
Channel.CreateUnbounded<Func<CancellationToken, Task>>();


Добавление задачи:
    public ValueTask EnqueueAsync(Func<CancellationToken, Task> job)
{
return _channel.Writer.WriteAsync(job);
}


Чтение задач:
    public IAsyncEnumerable<Func<CancellationToken, Task>> ReadAllAsync(
CancellationToken token
)
{
return _channel.Reader.ReadAllAsync(token);
}
}


Теперь можно положить работу в очередь:
await queue.EnqueueAsync(async token =>
{
await emailSender.SendAsync(user.Email, token);
});


А отдельный воркер будет выполнять задачи:
await foreach (var job in queue.ReadAllAsync(token))
{
await job(token);
}


В ASP.NET Core такую логику обычно выносят в BackgroundService:
protected override async Task ExecuteAsync(CancellationToken token)
{
await foreach (var job in queue.ReadAllAsync(token))
{
await job(token);
}
}


Такой подход помогает не держать HTTP-запрос открытым, если работу можно выполнить после ответа пользователю.

➡️ C# Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3🔥3