Git Top Libraries


Channel's geo and language: Russia, Russian
Category: Technologies


Топовые библиотеки из GitHub

Related channels

Channel's geo and language
Russia, Russian
Statistics
Posts filter


Forward from: .NET epeshk blog
.NET #opensource: Jint

Периодически буду рассказывать о различных Open Source проектах написанных на .NET (и не только)

Jint 3.8k ⭐️ — JavaScript интерпретатор, целиком написанный на C#. Поддерживает большое подмножество современного JS, позволяет вызывать как JS-код из дотнета, так и в обратную сторону: из JS вызывать .NET-код. Всё работает в одном процессе: не нужно мучаться с деплоем отдельного тяжеловесного движка.

Кроме очевидного переиспользования JS-кода, средствами Jint можно например реализовать в программе расширяемость — дать возможность пользователям писать свои выражения, функции, плагины на JavaScript или другом языке, который можно в него преобразовать. Например, так можно сделать бэкенд для no-code платформы, где пользователь работает с визуальным языком.

Также могут пригодиться:
- JavaScript Engine Switcher — единый фронтенд для вызова JS-кода из .NET с возможностью заменить движок
- Jurassic и NiL.JS — альтернативы Jint
- NFun, NCalc — интерпретаторы выражений. Полезны, если надо поддержать выполнение простых пользовательских выражений, а JavaScript — дополнительная сложность (не забываем про задачи-загадки вида {}+[] == []+{})

@epeshkblog | Поддержать канал


Минусы:
1. Сложности масштабирования: Хотя SignalR обеспечивает эффективную связь между сервером и клиентами, масштабирование может быть сложным, особенно если требуется обслуживать большое количество одновременных соединений.

2. Необходимость поддержки веб-сокетов: Для использования веб-сокетов, на которых основан SignalR для реального времени обновлений, требуется поддержка со стороны сервера и клиента. Некоторые среды могут иметь ограничения в этом отношении.

3. Сложности отладки: Использование асинхронной связи между сервером и клиентом может сделать отладку сложной, особенно при поиске проблем связанных с сетевым взаимодействием.


Несмотря на эти минусы, в большинстве случаев преимущества использования SignalR для обновления клиентских таблиц через веб-сокеты или long polling перевешивают его недостатки, особенно в задачах, где требуется обеспечить мгновенную доставку данных и реальное время в веб-приложениях.


Плюсы работы с SignalR:

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

2. Эффективное использование ресурсов: Поскольку SignalR использует механизмы долгосрочных соединений, такие как веб-сокеты или long polling, он может быть более эффективным по сравнению с традиционными методами опроса сервера на предмет обновлений.

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

4. Снижение нагрузки на сервер: Поскольку SignalR позволяет отправлять обновления только при необходимости, он может снизить нагрузку на сервер по сравнению с постоянным опросом клиентов на предмет изменений.


Forward from: George Drak
Всем привет. Может быть кому-то ещё пригодится. Иногда дебаггер в Rider не может показать значения некоторых переменных, особенно если проваливаться во внешние библиотеки. Выглядит это как ошибка Evaluation is not allowed: The thread is not at a GC-safe point. Оказывается, дебаггеру можно немного помочь, поотключав у приложения различные JIT-оптимизации при помощи переменных окружения.

SET COMPLUS_ZapDisable=1 NGen off (CLR)
SET COMPLUS_JitMinOpts=1 Disable as much JIT optimizations as possible (CoreCLR)
SET COMPlus_TieredCompilation=0 No tiered JIT, only do one pass (CoreCLR)
SET COMPLUS_ReadyToRun=0 Don't do netcore's analog to NGen (CoreCLR)

Это можно сделать прямо в конфиге запуска. После добавления этих настроек у меня стало показывать все значения во внутрянке типа Microsoft.Extensions.DependencyInjection.


https://learn.microsoft.com/ru-ru/aspnet/signalr/

SignalR - это библиотека для реализации в реальном времени веб-приложений. Она поддерживает несколько методов связи между сервером и клиентом, включая веб-сокеты, Server-Sent Events и long polling.


Forward from: .NET epeshk blog
Monitor

Конструкция lock (obj) { /* do something */ } в C# — синтаксический сахар для методов класса Monitor:

Monitor.Enter(obj);
try
{
// do something
}
finally
{
Monitor.Exit(obj);
}

Но класс Monitor — самодостаточный. Его использование напрямую, без конструкции lock позволяет реализовать несколько интересных механик.

Happy path

Метод Monitor.TryEnter позволяет зайти в критическую секцию, если она свободна от других потоков. Можно сделать разную логику в зависимости от того, есть ли конкуренция с другими потоками.

В библиотеке Serilog.Sinks.RawConsole я использовал TryEnter, чтобы реализовать следующую логику — если конкуренции нет, то log event рендерится в текст/json под локом, сразу в общий буфер. Если не повезло и лок занят — рендеринг текста происходит в локальный для потока буфер, затем берётся лок и результат копируется в общий буфер.

В итоге, рендеринг лог-сообщений в текст/json выполняется параллельно, с дополнительным бонусом в виде отсутствия копирования, если конкуренции нет (повезло, или используется асинхронная обёртка Serilog.Sinks.Async, Serilog.Sinks.Background)

Также Monitor.TryEnter позволяет задать таймаут ожидания блокировки.

Сигналы

Кроме блокировок, класс Monitor можно использовать для передачи сигналов между потоками.

Чтобы это сделать, вначале нужно захватить lock на объекте.

Затем, вызвав метод Monitor.Wait, можно заблокировать поток и освободить лок.

Другой поток может вызвать Pulse или PulseAll — тогда, при выходе из критической секции возобновится выполнение потоков, ждущих с помощью Wait. PulseAll сигнализирует все потоки, а Pulse — один (при этом, Pulse можно вызвать несколько раз чтобы сигнализировать нужное число потоков).

Пример с двумя потоками:

var obj = new object();

var t1 = new Thread(() =>
{
lock (obj)
{
Console.WriteLine("entered lock on thread 1");
Monitor.Wait(obj);
Console.WriteLine("got signal on thread 1");
}
});

var t2 = new Thread(() =>
{
Thread.Sleep(1000);
lock (obj)
{
Console.WriteLine("entered lock on thread 2");
Monitor.Pulse(obj);
Console.WriteLine("exiting lock on thread 2"); // ещё не разбудили первый поток, это случится лишь по выходу из лока.
}
});


t1.Start();
t2.Start();
t1.Join();
t2.Join();

Результат:
entered lock on thread 1
entered lock on thread 2
exiting lock on thread 2
got signal on thread 1

Пример с N потоками и M сигналами остаётся на самостоятельное изучение

Такой способ передачи сигналов я использовал в библиотеке Serilog.Sinks.Background для того, чтобы сигнализировать background-поток о появлении новых лог-сообщений. Но, с дополнительными доработками:
- логирующие потоки не ждут на локе друг друга — они выбирают, какой пойдёт сигнализировать через Interlocked
- один log event не активирует background-поток — нужно, чтобы в очереди набралось некоторое их количество
- на случай, если логов мало — background-поток активируется по таймауту. В итоге при отладке и выводе логов в консоль — они появляются на экране почти мгновенно, в 60 ФПС (дальше зависит от того, как быстро рендерит терминал)

Однако, такой способ очень рискованный — если никакой поток не вызвал Monitor.Wait, то сигнал, отправленный через Monitor.Pulse будет потерян, что может приводить к дедлокам. Избежать этого помогают более высокоуровневые примитивы синхронизации, но об этом будет уже следующий пост.

Метрики

Через свойство Monitor.LockContentionCount можно узнать, сколько раз за время выполнения программы потоки останавливались на блокировках, реализованных через класс Monitor. SpinLock, например, в эту статистику не входит, да и вообще не проявляется в метриках, чем уступает обычным локам в плане поддерживаемости.


@epeshkblog | Поддержать канал
█░░░░░░░░░░░░ 28 / 300


Forward from: .NET Разработчик
День шестьсот седьмой. #ЗаметкиНаПолях
Паттерн Options. Начало
Паттерн Options помогает связывать конфигурацию приложения со строго типизированными классами. Преимущество этого подхода перед получением каждого свойства конфигурации по отдельности (помимо сокращения объёма кода) в том, что есть возможность группировать связанные свойства, а также производить валидацию свойств.
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}

public class PositionOptions {
public const string Position = "Position";

public string Title { get; set; }
public string Name { get; set; }
}
Заметьте, что используется статическая переменная Position с путём к секции конфигурации (в данном случае "Position"), чтобы избежать опечаток (см. ниже). Получить значение в коде можно через внедрение зависимости IConfiguration:
private readonly IConfiguration _configuration;
Далее либо через вызов метода ConfigurationBinder.Bind:
var positionOptions = new PositionOptions(); _configuration.GetSection(PositionOptions.Position)
.Bind(positionOptions);
либо через вызов метода ConfigurationBinder.Get:
positionOptions =
_configuration.GetSection(PositionOptions.Position)
.Get();

Кроме того, можно добавить регистрацию параметров в сервисы:
public void ConfigureServices(IServiceCollection services) {
services.Configure(
Configuration.GetSection(
PositionOptions.Position));
// либо
services.AddOptions()
.Bind(Configuration.GetSection(
PositionOptions.Position));

}
И использовать через внедрение зависимости:
private readonly PositionOptions _options;
public TestModel(IOptions options) {
_options = options.Value;
}

Обновление значений
Что если нам нужно обновлять значения параметров во время работы приложения? IOptions устанавливается как Singleton в контейнере DI. Значения параметров устанавливаются при первом обращении к ним, и не могут быть изменены без рестарта. Именованные параметры (о них далее) не поддерживаются.

В этом случае вместо IOptions можно использовать один из двух вариантов:
1. IOptionsSnapshot
Поддерживает перезагрузку параметров и именованные параметры. Регистрируется как Scoped сервис. Поэтому обновлённые значения параметров будут доступны при следующем запросе к приложению. Однако из-за регистрации как Scoped, IOptionsSnapshot не может быть внедрён в Singleton сервисы.

2. IOptionsMonitor
Поддерживает перезагрузку параметров и именованные параметры. Регистрируется как Singleton сервис. Значения параметров доступны через options.CurrentValue (в отличие от Value в предыдущих случаях). Кроме того, поддерживается метод OnChange, в котором регистрируется делегат, обновляющий значения в коде при изменении конфигурации, а также, например, делающий запись в лог.

Продолжение следует…

Источник: https://app.pluralsight.com/library/courses/dotnet-core-aspnet-core-configuration-options/




Forward from: devdigest // dot net
Несмотря на то, что Microsoft активно развивает WPF и MAUI, Windows Forms не ушел в историю. В статье вы узнаете, что нового появилось Windows Forms с выходом .NET 6

https://devblogs.microsoft.com/dotnet/whats-new-in-windows-forms-in-net-6-0/

#WindowsForms #windows #forms #UI #net6


Лично я считаю, что за программирование на WPF,а тем более на WinForms надо давать бесплатно молоко





















20 last posts shown.