TGViewer
Channel Public Channel
C# 1001 notes

C# 1001 notes

@csharp_1001_notes

Регулярные короткие заметки по C# и .NET.

Просто о сложном для каждого.

admin - @haarrp
Subscribers
6.64K
Photos
419
Videos
14
Links
363
Recent Posts 16 shown
Post #911 498
🧩 C# Channels: сообщение попало в очередь. Почему обработчик его не получил?

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


using System.Threading.Channels;

var queue = Channel.CreateBounded<int>(
new BoundedChannelOptions(1)
{
FullMode = BoundedChannelFullMode.Wait
});

using var cts = new CancellationTokenSource();

var firstRead = queue.Reader.ReadAsync().AsTask();

var firstWorker = Task.Run(async () =>
{
try
{
var item = await firstRead.WaitAsync(cts.Token);
Console.WriteLine($"A: {item}");
}
catch (OperationCanceledException)
{
Console.WriteLine("A: canceled");
}
});

// Дожидаемся, чтобы первый воркер обработал отмену.
cts.Cancel();
await firstWorker;

var secondWorker = Task.Run(async () =>
{
await foreach (var item in queue.Reader.ReadAllAsync())
Console.WriteLine($"B: {item}");
});

await queue.Writer.WriteAsync(42);
queue.Writer.TryComplete();

await secondWorker;
await queue.Reader.Completion;

Console.WriteLine("Finished");


Разберите без запуска:

1. Что выведет программа? Возможны ли разные результаты?
2. Где окажется 42, если ни один воркер его не напечатает?
3. Почему Reader.Completion успешно завершится?
4. Чем отличаются эти две записи?


reader.ReadAsync().AsTask().WaitAsync(token)
reader.ReadAsync(token).AsTask()


Усложнение: отмена и запись происходят одновременно. Достаточно ли второй записи, чтобы гарантировать, что сообщение не потеряется?

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

👇 В какой момент ответственность за сообщение переходит от канала к воркеру?
Post #910 1.04K
Эта задача проверяет понимание Memory<T>, pooling, ownership, IAsyncEnumerable, cancellation и одной из самых неприятных категорий ошибок высокопроизводительного C# — когда GC защищает объект от удаления, но не защищает вас от повторного использования его содержимого.
Post #909 832
# C# 14: хитрая задача на ArrayPool, IAsyncEnumerable и время жизни памяти

Есть поток данных, из которого нужно читать сообщения построчно без лишних аллокаций.

Наивная реализация:


static async IAsyncEnumerable<ReadOnlyMemory<byte>> ReadLinesAsync(
Stream stream,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(4096);

try
{
while (true)
{
int read = await stream.ReadAsync(buffer, cancellationToken);

if (read == 0)
yield break;

yield return buffer.AsMemory(0, read);
}
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}


Использование:


await foreach (var data in ReadLinesAsync(stream))
{
queue.Add(data);
}


Код компилируется и выглядит эффективно.

Но в production данные внутри queue иногда внезапно меняются или повреждаются.

## Вопрос

Почему?

---

# Проблема

ReadOnlyMemory<byte> не владеет памятью.

Он всего лишь указывает на:


byte[] buffer


А этот массив взят из:


ArrayPool<byte>.Shared


После следующего:


ReadAsync(buffer)


содержимое массива перезаписывается.

А после:


ArrayPool<byte>.Shared.Return(buffer);


массив вообще может получить другой поток.

Получается:


yield memory

consumer сохраняет ссылку

buffer переиспользуется

старый ReadOnlyMemory показывает новые данные


Это логический аналог use-after-free, хотя runtime C# остаётся memory-safe.

---

# Задача

Исправьте API так, чтобы:

- использовался пул памяти;
- данные можно было безопасно хранить после yield;
- не происходило скрытого копирования каждого сообщения;
- consumer явно управлял временем жизни буфера;
- отмена работала через CancellationToken.

Подсказка: используйте


IMemoryOwner<byte>


---

# Один из вариантов решения


public sealed class Message : IDisposable
{
private IMemoryOwner<byte>? _owner;

public ReadOnlyMemory<byte> Data { get; }

public Message(IMemoryOwner<byte> owner, int length)
{
_owner = owner;
Data = owner.Memory[..length];
}

public void Dispose()
{
_owner?.Dispose();
_owner = null;
}
}


Чтение:


static async IAsyncEnumerable<Message> ReadAsync(
Stream stream,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
while (true)
{
IMemoryOwner<byte> owner =
MemoryPool<byte>.Shared.Rent(4096);

int read;

try
{
read = await stream.ReadAsync(
owner.Memory,
cancellationToken);
}
catch
{
owner.Dispose();
throw;
}

if (read == 0)
{
owner.Dispose();
yield break;
}

yield return new Message(owner, read);
}
}


Consumer:


await foreach (var message in ReadAsync(stream, ct))
{
using (message)
{
Process(message.Data);
}
}


Теперь память возвращается в pool только тогда, когда consumer закончил с сообщением.

---

# Главная ловушка

Даже такой код опасен:


ReadOnlyMemory<byte> saved;

await foreach (var message in ReadAsync(stream))
{
using (message)
{
saved = message.Data;
}
}

Console.WriteLine(saved.Length);


После Dispose() память больше не принадлежит consumer.

Сам ReadOnlyMemory<byte> технически существует, но использовать его содержимое уже нельзя.

---

# Вопрос уровня Senior

Как изменить API так, чтобы разработчику было сложнее случайно сохранить ReadOnlyMemory<byte> после Dispose()?

Дополнительно подумайте:


ArrayPool<T>
vs
MemoryPool<T>
vs
обычный byte[]


и ответьте, когда zero-copy действительно быстрее, а когда управление lifetime становится дороже простой копии.
Post #908 993
# C# 14: конкурентный кеш без race condition

Реализуйте потокобезопасный кеш:


public sealed class AsyncCache<TKey, TValue>
where TKey : notnull
{
public Task<TValue> GetOrCreateAsync(
TKey key,
Func<CancellationToken, Task<TValue>> factory,
CancellationToken cancellationToken = default)
{
// TODO
}
}


Условия: если 100 потоков одновременно запросят один key, factory должна выполниться только один раз. Остальные ждут тот же Task. Если вычисление завершилось ошибкой - запись удаляется из кеша. Отмена одного клиента не должна отменять работу для остальных. Глобальный lock использовать нельзя.

Вопрос: как избежать race condition между созданием общего Task и удалением упавшего значения из кеша?
Post #907 1.02K
🔍Тестовое собеседование с Senior C# разработчиком уже завтра

15 сентября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle C# разработчика.

Как это будет:
📂 Александр Моргунов, старший C# разработчик с опытом 7+ лет в Европейских высоконагруженных сервисах, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Александр будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Александру

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для C# разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_csharp_bot

Реклама.
О рекламодателе.
Post #906 1.4K
🔧 Как передать многострочный PEM через Aspire в ASP.NET Core

Сертификаты и ключи в PEM содержат переносы строк, которые могут создавать проблемы при передаче через параметры Aspire. Damien Bod показал обходной вариант для локальной разработки с User Secrets и развёртывания в Azure.

Схема простая:

* закодировать PEM в однострочный Base64
* сохранить значение в конфигурации AppHost под ключом Parameters:ИмяПараметра
* объявить приватный ключ через AddParameter(..., secret: true)
* передать параметр приложению через WithEnvironment
* в ASP.NET Core декодировать Base64 обратно в исходный PEM

В статье есть helper-класс для преобразования, настройка AppHost и пример создания сертификата через X509Certificate2.CreateFromPem.

Base64 сохраняет переносы строк при передаче. Приватный ключ после кодирования остаётся секретом: Base64 не обеспечивает шифрование.

https://damienbod.com/2026/09/01/using-multiline-parameters-for-aspire-and-asp-net-core-with-user-secrets-and-azure-default-deployments/
Software Engineering Using multiline Parameters for Aspire and ASP.NET Core with user secrets and Azure default deployments Multiple line secrets or configuration do not work in Aspire per default. An example of this is using a PEM file for certificates. This posts shows how the multiple line configuration parameters ca…
Post #905 1.49K
Согласны ?
Post #904 1.56K
⚡️ Задачи с технических собеседований в одном репозитории

Tech-OA-Interview-Questions - подборка задач из онлайн-тестирований и интервью в технологических компаниях. Пригодится для подготовки к алгоритмическим этапам отбора.

OA, или Online Assessment, - тестирование, которое кандидат обычно проходит перед собеседованиями. В репозитории собраны материалы для подготовки к таким заданиям, в том числе к отбору в Amazon.

Можно использовать как список для практики: решать задачи с таймером, оценивать сложность решения и проверять граничные случаи.

https://github.com/perixtar/Tech-OA-Interview-Questions
Post #902 1.37K

Forwarded from C# (C Sharp) programming

✔️ Polly становится платной, но у .NET остаётся бесплатная альтернатива

Polly много лет была одной из главных библиотек .NET для устойчивости к временным сбоям: retry, timeout, fallback, rate limiting и circuit breaker.

Теперь Polly движется в сторону платной модели, но Microsoft.Resilience по-прежнему можно использовать бесплатно.

С .NET 8 работа с resilience стала заметно проще: появился новый API Polly и официальные библиотеки Microsoft для построения resilience pipelines.

Что можно настроить:

- Retry
- Fallback
- Timeout
- Rate limiting
- Circuit breaker

Хороший разбор того, как собирать устойчивые cloud-приложения на современном .NET:

https://milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet
Post #901 1.45K
.NET и Владимир: отличный повод совместить митап и выходные в городе с историей

Офлайн-мероприятий для .NET-разработчиков сейчас не так много, а тут получается приятное комбо: встреча с другими разработчиками вечером в пятницу и возможность остаться на выходные в городе с историей.

В программе доклады от разработчиков Altenar и Рови Тех (часть Т-Банка):
— Async/await — асинхронность, которую можно читать.
— Как не терять данные при асинхронной интеграции программных систем.
— EF Core + PostgreSQL: за рамками CRUD.


Кстати, ещё на митапе запланированы активности для программистов: адаптации известных игр ("Сапер", "Крестики-нолики", "Гонки"), где для победы понадобится понимание математики и вероятностей.

Участие бесплатное, а ещё можно сэкономить на проезде — организаторы разыграют несколько билетов на "Ласточку" среди участников.

Для участия в розыгрыше:
1. Зарегистрируйтесь на митап.
2. Напишите «Хочу на .NET-митап на Ласточке» на почту aleksei.korneev@altenar.com с почты, указанной при регистрации.

Итоги розыгрыша подведём 14 сентября.


Регистрируйтесь, планируйте поездку и до встречи во Владимире!
Post #899 1.35K
Полноценный Lisp можно уместить всего в 99 строк C.

Внутри при этом:

- 21 примитив
- REPL
- сборщик мусора Cheney GC
- числа с плавающей точкой
- указатели
- типы значений

И всё это без `struct`-тегов, без внешних библиотек и без обычных динамических аллокаций для представления объектов.

Главный трюк - NaN boxing.

IEEE 754 оставляет много битов внутри специальных NaN-значений. Их можно использовать как скрытое хранилище:

- часть битов кодирует тип
- до 48 бит можно использовать под указатель
- обычные double при этом остаются обычными числами

В итоге одно 64-битное значение может представлять и число, и указатель, и другие типы данных.

Очень красивый пример того, как устройство IEEE 754 можно использовать для построения компактного рантайма языка.
Post #897 1.94K
Вышел Aspire 13.5 - обновление с упором на интерфейс и удобство повседневной разработки.

Что добавили:

- обновлённый Dashboard и новый дизайн aspire.dev
- фильтрацию логов и трассировок по тексту, времени и числам
- более понятные ошибки health-check
- загрузку файлов прямо через команды AppHost
- окна прогресса с возможностью отмены
- полноценный терминал прямо внутри Dashboard через WithTerminal()
- поддержку persistent volumes для Kubernetes
- работу с существующими Azure-ресурсами из других resource group, подписок и tenants
- установку Aspire CLI через Homebrew, WinGet, npm, Nix, mise и NuGet

Отдельно удобно, что теперь часть инфраструктурных настроек можно описывать прямо в AppHost на C# или TypeScript, без постоянного ухода в YAML.

https://devblogs.microsoft.com/aspire/whats-new-aspire-13-5/
Post #896 1.75K
Как собрать production-ready CRUD на ASP.NET Core

Telerik разобрала не просто базовый CRUD, а структуру приложения, которую уже можно нормально развивать дальше.

В примере используются:

- ASP.NET Core Web API
- Entity Framework Core
- PostgreSQL
- DTO
- Service layer
- Repository pattern
- AutoMapper
- FluentValidation
- Swagger / OpenAPI

Отдельный акцент сделан на разделении ответственности.

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

Также разбираются:

- создание и настройка проекта
- подключение PostgreSQL
- миграции EF Core
- CRUD endpoints
- обработка ошибок
- валидация
- mapping между entity и DTO
- организация структуры проекта

Хороший материал, если базовый CRUD уже умеешь писать, но хочешь привести проект к более нормальной production-структуре.

https://telerik.com/blogs/creating-production-ready-crud-application-aspnet-core

#aspnetcore #dotnet
Post #895 1.94K
⚡ Race Conditions в ASP.NET Core - как они появляются и почему их сложно ловить

В статье Assis Zang разбирается, что происходит, когда несколько запросов одновременно работают с общим состоянием и начинают вмешиваться друг в друга.

Внутри:

- откуда берутся race conditions
- почему проблема может проявляться нестабильно
- как воспроизвести конкурентный доступ
- какие ошибки возникают при работе с shared state
- как использовать синхронизацию и безопасные паттерны
- почему потокобезопасность важна даже в обычном web API

Полезно для .NET-разработчиков, которые работают с многопоточностью, shared state и высоконагруженными ASP.NET Core-приложениями.

https://telerik.com/blogs/understanding-race-conditions-aspnet-core
Telerik Blogs Understanding Race Conditions in ASP.NET Core Explore the concept of race conditions in ASP.NET Core, understand how to identify them and learn strategies to protect applications against this type of issue.
Post #894 1.44K

Forwarded from Machinelearning

✔️ Hugging Face прощупывает интерес покупателей

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

По данным источников, сейчас компанию оценивают примерно в 1,3 млрд долларов, тогда как в 2023 году оценка доходила до 4,5 млрд, - за три года почти в три с половиной раза ниже.

Наиболее вероятными покупателями называют нынешних инвесторов Hugging Face - Google, Amazon, Nvidia, Intel и Salesforce.
bloomberg.com

✔️ Alibaba запустила видеогенератор Wan3.0

Модель собирает тридцатисекундные ролики из текстовых документов, таблиц, презентаций и веб-страниц. В новой версии лучше работают референсы и реконструкция реальных объектов, а базовая длина ролика выросла.

Alibaba целится в производство рекламы, коротких сериалов и музыкальных клипов. До официального запуска модель была в открытой бете.

Иностранцы получают доступ к API через Alibaba Cloud. Секунда видео стоит 10 центов в 720p и 20 центов в 1080p, то есть полный тридцатисекундный ролик в 1080p обойдется в 6 долларов.
reuters.com

✔️ Antigravity теперь управляется с телефона

Агентом можно рулить со смартфона или из браузера, ничего дополнительно не устанавливая. В интерфейсе видно сессии в реальном времени, туда же ставятся задачи и оттуда проверяются результаты.

На телефон приходят уведомления, когда агент закончил работу или ждет от человека подтверждения. Подключиться можно сразу к нескольким машинам и быстро между ними переключаться, причем монитор хосту не нужен - Antigravity запускается и работает и без него.

Обновление раскатывают постепенно, первыми его получают подписчики Google AI Ultra.
antigravity.google

✔️ FDA впервые разрешило автономного робота для забора крови

Американский регулятор выдал разрешение по процедуре системе Aletta голландского стартапа Vitestro. Робот делает всю процедуру сам: накладывает жгут, дезинфицирует кожу, находит вену, вводит иглу, меняет пробирки, убирает расходники и заклеивает прокол.

Вены он ищет ближней инфракрасной съемкой, ультразвуком и допплерографией - ими же отличает вену от артерии. В клинических испытаниях на 1600 пациентах игла попадала с первой попытки в 94,5% случаев.

Aletta рассчитана на амбулаторный прием взрослых. Один оператор может вести сразу три таких аппарата.
fda.gov

✔️ В Южной Корее микроэлектроника догоняет медицину по конкурсу в ВУЗы

На фоне ИИ-бума корейские абитуриенты пошли в микроэлектронику. По данным Jongno Academy, частного центра подготовки к поступлению, средний проходной балл на профильные специальности в ведущих вузах дошел до 96,2. Медицинские факультеты, где конкурс исторически самый высокий в стране, держат 97,2.

Университеты вместе с Samsung Electronics и SK Hynix запускают целевые программы с гарантированным трудоустройством. А школьники, чтобы поступить на инженерные направления, все лето занимаются в специализированных центрах Сеула.
ft.com

@ai_machinelearning_big_data

#news #ai #ml
Post #889 1.42K
⚡️Актуальные темы .NET на DotNext 2026

В .NET одновременно происходит много интересного: C# получает новые возможности, .NET 10 меняет расклад между Native AOT и JIT, а в разработке появляются ИИ-агенты, которые берут на себя часть инженерной работы.
На DotNext 2026 разберем как вещи, которые происходят на уровне машинного кода, так и вполне прикладные вопросы архитектуры и разработки.

📅 25–26 сентября, Москва + online

Выбрали 8 тем из программы, среди которых не только доклады, но и хардкорный воркшоп, чтобы показать этот диапазон:

— как заставить Transactional Outbox одновременно быть строгим и параллельным;
— зачем ASP.NET Core модульный монолит и как собрать его без микросервисов;
— где Native AOT выигрывает у JIT в .NET 10;
— что происходит с циклами, inlining и bounds checks в C# и Go;
— как меняется SDLC, когда в команде появляются ИИ-агенты;
— что принесут discriminated unions в C# 15;
— как проектировать асинхронное взаимодействие в распределенных системах (воркшоп).

Все подробности — в карточках и на сайте конференции.

🌟По промокоду csharp1001notes — персональные билеты дешевле

Программа DotNext

Купить билет
Older posts →

About this channel

How can I read @csharp_1001_notes without a Telegram account?
TGViewer shows the public web preview Telegram publishes for C# 1001 notes: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does C# 1001 notes have?
C# 1001 notes (@csharp_1001_notes) has 6.64K subscribers on Telegram, refreshed roughly every 30 minutes.
Does C# 1001 notes know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
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 →