C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام C# (C Sharp) programming
تُعد قناة C# (C Sharp) programming (@csharp_ci) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 18 130 مشتركاً، محتلاً المرتبة 7 075 في فئة التكنولوجيات والتطبيقات والمرتبة 36 514 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 18 130 مشتركاً.
بحسب آخر البيانات بتاريخ 25 أغسطس, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -72، وفي آخر 24 ساعة بمقدار 5، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 14.84%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 7.23% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 2 691 مشاهدة. وخلال اليوم الأول يجمع عادةً 1 311 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 0.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل .net, api, логика, архитектура, string.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 26 أغسطس, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
var user = await pipeline.ExecuteAsync(
async token => await httpClient.GetAsync("api/users", token)
);
Чистый код, единая стратегия обработки ошибок и меньше боли при росте микросервисов.
Если пишете на C# и строите production-системы — Resilience Pipelines стоит добавить в свой toolbox. ⚙️
builder.Services.AddRateLimiter(options =>
{
options.AddPolicy("fixed-by-ip", httpContext =>
RateLimitPartition.GetFixedWindowLimiter(
partitionKey: httpContext.Connection.RemoteIpAddress?.ToString(),
factory: _ => new FixedWindowRateLimiterOptions
{
PermitLimit = 10,
Window = TimeSpan.FromMinutes(1)
}));
});
В этом примере один IP может сделать максимум 10 запросов за минуту.
Но использовать такой подход вслепую не стоит.
Причина простая: реальные пользователи могут находиться за NAT, прокси или корпоративным шлюзом и иметь один внешний IP. В итоге лимит одного человека начнёт влиять на остальных.
Поэтому для авторизованных пользователей обычно лучше ограничивать запросы по уникальному userId.
А rate limit по IP оставлять для анонимных endpoint'ов, защиты от простых ботов или как дополнительный слой защиты.
Install-Package Steeltoe.Discovery.Consul
Регистрируем discovery:
builder.Services
.AddServiceDiscovery(o => o.UseConsul());
В appsettings.json указываем Consul и параметры сервиса:
"Consul": {
"Host": "localhost",
"Port": 8500,
"Discovery": {
"ServiceName": "reporting-service",
"Hostname": "reporting-api",
"Port": 8080
}
}
А дальше самое полезное:
builder.Services
.AddHttpClient<ReportingServiceClient>(client =>
{
client.BaseAddress = new Uri("http://reporting-service");
})
.AddServiceDiscovery()
.AddRoundRobinLoadBalancer();
То есть HttpClient ходит не на конкретный IP:port, а на логическое имя сервиса.
Steeltoe через Consul получает живые инстансы, а RoundRobinLoadBalancer распределяет запросы между ними.
Это особенно полезно, когда сервисы часто пересоздаются, IP меняются, а хардкодить адреса уже невозможно.
По сути, клиентская часть получает простой pipeline:
service name → Consul → healthy instances → load balancing → HTTP request
Для микросервисов на .NET это намного чище, чем городить собственный discovery layer.break и continue: теперь можно явно указать, из какого цикла выходить или какой цикл продолжать. Ещё появились union patterns и улучшенная проверка исчерпывающих случаев для закрытых иерархий типов.
В Runtime добавили оптимизации async`/`await, включая runtime async tiering и tail-await. Отдельно продолжают развивать NativeAOT и JIT.
В SDK NativeAOT-версия dotnet CLI теперь включена по умолчанию, как и MSBuild Server. У dotnet test появились общий --timeout, ограничение --maximum-failed-tests и поддержка запуска тестов на устройствах .NET MAUI.
ASP.NET Core получил автоматическую приостановку неактивных Blazor circuits, кеширование SSR через CacheView, новые анализаторы Blazor и встроенную локализацию validation-сообщений.
Ещё из приятного: HTTP request compression, API для DNS-записей, парольная защита ZIP, Complex<T>, улучшения LINQ в EF Core и поддержка Half в SQLite.
.NET 11 Preview 7 вышел 11 августа 2026 года и уже доступен для тестирования.
https://devblogs.microsoft.com/dotnet/dotnet-11-preview-7/Application внезапно начал зависеть от Infrastructure.
Code Review тоже не гарантирует, что такое заметят.
Для этого можно использовать Architecture Tests — тесты, которые проверяют не бизнес-логику, а структуру проекта.
Например, через NetArchTest.Rules:
[Fact]
public void Application_Should_Not_Depend_On_Infrastructure()
{
var result = Types
.InAssembly(ApplicationAssembly)
.ShouldNot()
.HaveDependencyOn("MyApp.Infrastructure")
.GetResult();
Assert.True(result.IsSuccessful);
}
Теперь случайный:
Application → Infrastructure
сломает CI так же, как обычный упавший unit-тест.
Можно зафиксировать и naming convention:
[Fact]
public void Handlers_Should_End_With_Handler()
{
var result = Types
.InAssembly(ApplicationAssembly)
.That()
.ImplementInterface(typeof(ICommandHandler<>))
.Should()
.HaveNameEndingWith("Handler")
.GetResult();
Assert.True(result.IsSuccessful);
}
Или заставить сервисы быть sealed:
Types
.InAssembly(ApplicationAssembly)
.That()
.HaveNameEndingWith("Service")
.Should()
.BeSealed();
Особенно полезно это становится в больших Clean Architecture / DDD / Modular Monolith проектах.
Вместо документа:
❌ «Application не должен зависеть от Infrastructure»
получаем исполняемое правило:
✅ нарушил архитектуру → тест упал → PR не прошёл
По сути, архитектура превращается из договорённости команды в часть автоматической проверки проекта.
#CSharp #DotNet #Architecture #Testingawait, хотя под капотом работают две независимые очереди:
Requester -> request -> Responder
Requester <- response <- Responder
В RabbitMQ запрос обычно содержит ReplyTo и уникальный CorrelationId, чтобы клиент понял, к какому запросу относится ответ.
В NATS для ответа создаётся отдельный inbox subject.
Упрощённая идея на C#:
var requestId = Guid.NewGuid();
await bus.SendAsync(new PriceRequest(
RequestId: requestId,
ProductId: productId
));
var response = await responses
.WaitForAsync<PriceResponse>(
requestId,
timeout: TimeSpan.FromSeconds(2),
cancellationToken);
Плюсы действительно значительные:
- отправителю не нужно знать адрес обработчика;
- responder можно горизонтально масштабировать;
- брокер помогает пережить кратковременный сбой сервиса;
- приложения остаются слабо связанными.
Но это не «HTTP, только через RabbitMQ».
Пока requester ждёт результат, взаимодействие остаётся логически синхронным. Поэтому обязательно нужны:
- таймаут и CancellationToken;
- уникальный CorrelationId;
- обработка поздних и повторных ответов;
- идемпотентность responder;
- ограничение количества одновременных запросов;
- трассировка через обе очереди.
Особенно опасный случай:
Service A ждёт B
Service B ждёт C
Service C ждёт A
Брокер работает, сообщения доставляются, но вся система стоит.
Request-response через messaging полезен, когда нужны location transparency, балансировка обработчиков и единый транспорт между сервисами.
Для простого короткого запроса HTTP или gRPC часто остаются понятнее и быстрее.
Главное правило:
брокер убирает прямую связь между сервисами, но не убирает зависимость от ответа.safe — но это не аналог Rust
В C# 15 тестируется новый контекстный модификатор safe для кода на границе с нативной памятью.
Главная проблема P/Invoke: компилятор видит сигнатуру метода, но не может проверить, насколько безопасно ведёт себя код внутри подключённой библиотеки. Теперь разработчик должен явно зафиксировать решение:
[LibraryImport("libc")]
internal static safe partial int getpid();
[LibraryImport("libc")]
internal static unsafe partial nuint strlen(byte* value);
safe означает, что вызов не требует `unsafe`-контекста со стороны пользователя API.
unsafe предупреждает: безопасность зависит от условий, которые компилятор проверить не может. Такой метод разрешено вызывать только внутри блока:
unsafe
{
nuint length = strlen(pointer);
}
Та же логика применяется к полям структур с явным расположением памяти:
[StructLayout(LayoutKind.Explicit)]
struct Packet
{
[FieldOffset(0)]
public safe long Id;
[FieldOffset(0)]
public unsafe nint Pointer;
}
Если не указать ни safe, ни unsafe, компилятор выдаст ошибку при включённых новых правилах безопасности. :contentReference[oaicite:0]{index=0}
Важный нюанс: safe не анализирует нативный код и не доказывает его безопасность. Это явное обещание автора API, которое делает потенциально опасные границы заметными при ревью.
C# постепенно меняет подход к unsafe: риск должен быть обозначен в контракте метода и локализован в конкретных участках программы, а не спрятан внутри большого `unsafe`-класса.
Пока эта модель находится в preview и может измениться до стабильного выпуска C# 15.double небольшие ошибки округления постепенно накапливаются. Особенно плохо, когда рядом оказываются очень большие и очень маленькие числа.
Обычный вариант:
double sum = 0;
foreach (double value in values)
{
sum += value;
}
Более точный вариант:
public static double KahanSum(ReadOnlySpan<double> values)
{
double sum = 0;
double compensation = 0;
foreach (double value in values)
{
double adjusted = value - compensation;
double next = sum + adjusted;
compensation = (next - sum) - adjusted;
sum = next;
}
return sum;
}
Переменная compensation сохраняет часть числа, потерянную при округлении, и возвращает её в следующее сложение.
Использование:
double[] values = { 0.1, 0.2, 0.3, 0.4 };
double result = KahanSum(values);
Метод полезен для:
- научных расчётов;
- статистики и аналитики;
- обработки сигналов;
- симуляций;
- накопления миллионов небольших значений.
ReadOnlySpan<double> позволяет передавать массивы и участки памяти без дополнительных копирований.
Алгоритм требует нескольких дополнительных операций на каждом шаге, зато заметно уменьшает накопленную погрешность.
Для денежных расчётов по-прежнему лучше использовать decimal. А когда нужна скорость double и повышенная численная устойчивость – пригодится Kahan Summation.