Ответы пользователя по тегу C#
  • Есть ли какой-нибудь способ конвертировать массив или коллекцию List в synchronizedCollection?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    SynchronizedCollection<T> - это легаси из .NET фреймворка, в современном рантмайме ты его не найдешь.
    Могу предложить использовать:
    - BlockingCollection<T>
    - Channel<T>

    Если есть возможность, то конвертируй задачу на Scatter/Gather манеру и необходимость в этих структурах данных отпадет.
    Ответ написан
    Комментировать
  • Почему потоки накапливаются и не уничтожаются?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Смотреть в сторону разницы: Process.GetCurrentProcess().Threads.Count и ThreadPool.ThreadCount
    Скорее всего какой-то сервис создает множество потоков (ручных) и держит ссылки на них, т.к. поток это объект ядра и он должен быть уничтожен когда на него перестают ссылаться, либо это просто поток, который не завершатся (while (true) какой-нибудь)
    Ответ написан
    2 комментария
  • В чём принципиальное отличие Eager/Explicit Loading от прямого использования Join-ов через LINQ в контексте EF Core?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    То что ты описал - разные понятия.

    Например, у тебя есть one-to-many и это представляется списком (ICollection).
    class User
    {
         public string Name { get; set; }
         public ICollection<Subscription> Subscriptions { get; set; }
    }


    Eager/Explicit/Lazy Loading

    Это КОГДА ты данные будешь получать.

    Тогда действия будут следующими:
    - Eager - не важно нужны тебе эти данные или нет - они все равно будут загружены. Тут ты сразу получишь все подписки (Subscriptions) даже если тебе просто нужно узнать Name
    - Lazy - они будут загружены, только когда обратишься к этому полю, т.е. в момент обращения к полю Subscriptions
    - Explicit - это стратегия когда ты сначала подгружаешь объекты в DbContext, а потом (в будущем) когда понадобятся загрузить из памяти - без сетевых запросов. Это уже про метод Load() у DbContext.

    Select/SelectMany/GroupMany

    Это ЧТО ты хочешь получить

    Пример все тот же:
    - Select - например, тебе нужно получить только имена, тогда ты создаешь анонимные объекты:
    context.Users.Select(u => new { u.Name });
    - SelectMany - тебе нужен только список подписок всех пользователей из списка
    context.Users.Where(u => someIds.Contains(u.Id)).SelectMany(u => u.Subscriptions); // Не уверен что запрос корректный

    - GroupBy - это уже JOIN

    Смысл ты понял - это разные зоны ответственности: КОГДА получать данные и КАКИЕ данные получать
    Ответ написан
    3 комментария
  • Как правильно расшифровать данные из изображения в c#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Нашел много недочетов, но главная ошибка здесь:
    char charToEncode = textToEncrypt[charIndex++];
    
                        byte[] colorBytes = new byte[] { originalColor.R, originalColor.G, originalColor.B };
                        for (int i = 0; i < 3; i++)
                        {
                            int bitIndex = (bitsPerChannel * i); 
                            if (bitIndex < 8)
                            {
                                colorBytes[i] = (byte)((colorBytes[i] & ~1) | ((charToEncode >> bitIndex) & 1));
                            }
                        }


    Я так полагаю, что символы сообщения кодируются в LSB, но проблема здесь в том, что кодируются только последние 3 бита - остальное (8 - 3 = 5 битов теряются). Т.е. сообщение восстановить никак

    + Сам цикл выглядит очень странно.
    Главный вопрос - зачем?
    Параметризовать алгоритм стеганографии подобным образом не очень оптимально, т.к. каждый создается с использованием тех или иных фич, который строго захардкожены и используют особенности конкретного формата. Цикл + проверка здесь только ухудшают понимание кода (ИМХО)
    Убери этот цикл, т.к. во-первых, станет понятнее, во-вторых, условие внутри при этой константе всегда выполняется.

    Теперь про декодирование:
    for (int i = 0; i < 3; i++)
                    {
                        int bitIndex = (bitsPerChannel * i);
                        if (bitIndex < 8)
                        {
                            charCode |= (byte)((encodedColor.ToArgb() >> bitIndex) & 1);
                            if (bitIndex <= 2)
                            {
                                charCode <<= bitsPerChannel;
                            }
                        }
                    }

    Вот этот участок тоже неправильно работает, т.к. ты кодируешь символы в LSB, а читаешь последние 3 бита - из них только 1 бит содержит данные.
    Ответ написан
    Комментировать
  • Объясните мне на пальцах рекурсию Фибоначчи F(4, например). Это самый простой алгоритм, а я не могу понять. Что мне делать?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Сначала n=2, затем n=0, потом снова n=2

    Рекурсивные функции лучше визуализировать в виде дерева вызовов. В данном случае, это будет бинарное дерево, т.к. 1 функция (F(n)) может вызвать максимум 2 подфункции (F(n - 1) и F(n -2)).
    Теперь самое интересное - представление в отладчике.
    Вспомни, что функция заканчивается return F(n -1) + F(n - 2). Ответ на твой вопрос кроется здесь.
    На самом деле эта конструкция разворачивается в нечто подобное:
    int prev = F(n - 1);
    int prevPrev = F(n - 2);
    return prev + prevPrev;

    На словах:
    1. Ты вызываешь корневой F(2) - n = 2
    2. Дебагер заходит в функцию и опускается до return F(n - 1) + F(n - 2)
    3. Заходит в F(n - 1) - n = 1
    4. Эта функция возвращает 1 - ты снова в родительской функции n = 2
    5. Заходит в F(n - 2) - n = 0
    6. Эта функция возвращает 1 - ты снова в родительской функции n = 2
    7. Родительская (исходная) функция возвращает сумму - 1 + 1
    Ответ написан
    1 комментарий
  • Почему иногда не создаются автоматически свойства и команды mvc wpf?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Это называется IntelliSense - технология автодополнения кода.
    Иногда не срабатывает, потому что:
    - либо код неправильно написан и плагин его не понимает
    - либо индексация не закончилась
    - либо действительно нельзя ничего дополнить
    - либо ошибке в самом плагине

    По твоему вопросу возможно есть тут ответ - https://stackoverflow.com/questions/47595772/custo...
    Ответ: влияет расположение элементов в коде. по ответу все должно идти в таком порядке:
    1. Окно
    2. DataContext
    3. Твой код
    4. AttachedProperty
    Ответ написан
    Комментировать
  • Почему gpu вычисления ILGPU медленнее в 10 раз чем CPU?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Вот из-за этого:
    // Initialize ILGPU.
         Context context = Context.CreateDefault();
         Accelerator accelerator = context.CreateCLAccelerator(1);//context.GetPreferredDevice(preferCPU: false)  .CreateAccelerator(context);
    
         // Load the data.
         using  MemoryBuffer1D<float, Stride1D.Dense> deviceData = accelerator.Allocate1D(input);
         using MemoryBuffer1D<float, Stride1D.Dense> deviceOutput = accelerator.Allocate1D<float>(output);
    
         // load / precompile the kernel
         Action<Index1D, ArrayView<float>, ArrayView<float>> loadedKernel =
             accelerator.LoadAutoGroupedStreamKernel<Index1D, ArrayView<float>, ArrayView<float>>(Kernel);
    
    
         // finish compiling and tell the accelerator to start computing the kernel
             loadedKernel((int)deviceOutput.Length, deviceData.View, deviceOutput.View);
             accelerator.Synchronize();


    Объяснение: ты в каждом тесте постоянно создаешь новые объекты, которые необходимы для работы фреймворка. Это должно быть тяжелые объекты (много содержат, тяжело инициализируются).
    Вынеси их инициализацию из-вне метода в какой нибудь Setup метод. Раз уж ты пользуешься BenchmarkDotNet, то вот помощь с этим

    UPD: оптимизировал бенчмарк - теперь GPU быстрее
    public class SampleBenchmark
    {
        static void Kernel(Index1D i, ArrayView<float> data, ArrayView<float> output)
        {
            output[i] = data[i % data.Length];
        }
        public static IEnumerable<object[]> Arguments => new[] {new object[]{new float[1000000], new float[1000000]} };
        private float[] _outputBuffer = new float[1000000];
        private float[] _inputBuffer = new float[1000000];
        
        private Context? _context;
        private Accelerator? _accelerator;
        private Action<Index1D, ArrayView<float>, ArrayView<float>>? _loadedKernel;
        private MemoryBuffer1D<float, Stride1D.Dense>? _deviceData;
        private MemoryBuffer1D<float, Stride1D.Dense>? _deviceOutput;
        
        [GlobalSetup]
        public void Setup()
        {
            var random = new Random();
            for (var i = 0; i < _inputBuffer.Length; i++)
            {
                _inputBuffer[i] = random.NextSingle();
            }
            
            _context = Context.CreateDefault();
            _accelerator = _context.GetPreferredDevice(preferCPU: false).CreateAccelerator(_context);
            _loadedKernel = _accelerator!.LoadAutoGroupedStreamKernel<Index1D, ArrayView<float>, ArrayView<float>>(Kernel);
            _deviceData = _accelerator!.Allocate1D(_inputBuffer);
            _deviceOutput = _accelerator!.Allocate1D(_outputBuffer);
        }
    
        [GlobalCleanup]
        public void TearDown()
        {
            _context?.Dispose();
            _accelerator?.Dispose();
            _deviceData?.Dispose();
            _deviceOutput?.Dispose();
        }
        [ArgumentsSource(nameof(Arguments))]
        [Benchmark]
        public void GPUTest(float[] input, float[] output)
        {
            // finish compiling and tell the accelerator to start computing the kernel
            _loadedKernel!((int)_deviceOutput.Length, _deviceData.View, _deviceOutput.View);
            _accelerator!.Synchronize();
        }
    
        [Benchmark]
        [ArgumentsSource(nameof(Arguments))]
        public void CpuTest(float[] input, float[] output)
        {
            for (var i = 0; i < input.Length; i++)
            {
                output[i] = input[i];
            }
        } 
    }


    | Method  | input           | output          | Mean      | Error    | StdDev   |
    |-------- |---------------- |---------------- |----------:|---------:|---------:|
    | GPUTest | Single[1000000] | Single[1000000] |  61.18 us | 0.101 us | 0.095 us |
    | CpuTest | Single[1000000] | Single[1000000] | 243.54 us | 3.114 us | 2.600 us |
    Ответ написан
    2 комментария
  • Как использовать webapp проект как библиотеку?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Во-первых, почти любое веб приложение - консольное. Т.е. не оконное, не служба.
    Во-вторых, если тебе нужен WebHook, то у Telegram.Bot есть пример, как это сделать (используется ASP.NET Core) - https://github.com/TelegramBots/Telegram.Bot.Examp...
    В-третьих, не стоит делать выполняемые приложения (консольные, веб, сервисы) зависимыми от других - это плохо.
    Ответ написан
    3 комментария
  • Рестарт сервиса?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Дополню: можно запустить это все в докере с установкой флага рестарта unless-stopped. Тогда нужный контейнер:
    1. Будет запускаться во время старта системы
    2. Если вручную остановишь (контейнер), то запускаться после старта системы не будет
    3. При завершении с ошибкой контейнер будет перезапущен

    systemd - нормальный вариант для ЛИНУКСОВ (некоторые дистрибутивы его не имеют - их меньшинство поэтому можно не заморачиваться), но не для *nix - например, для mac будет launchd, для bsd - init. Это разные реализации и не совместимы с systemd. (Про винду молчу).
    Поэтому если хочется более-менее кросс-платформы, то стоит:
    1. Заранее создать нужные скрипты для создания конфигов systemd/launchd/bsd/windows service
    2. Установить docker и запускать через него

    P.S. конечно тащить за собой целый докер для одной программы это моветон, но живут же как-то джаваскриптисты со своими node_modules
    Ответ написан
    Комментировать
  • Автоматическая генерация классов на основе других классов?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Для C# это можно сделать 2 путями (без учета ручного создания):
    - Source Generators
    - Генерация IL кода (динамическая сборка)

    Лично я за 1 вариант, т.к. он будет быстрее в рантайме (все уже скомпилировано).
    Ответ написан
    2 комментария
  • Как правильно будет делать разделение для движения и ввода?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    В InputController держишь ссылку на Person.
    Когда происходит ввод, то просто вызываешь нужный метод у твоего Person
    Ответ написан
    Комментировать
  • Как передать данные в exe файл на C# при загрузке?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    1. Передавать имя пользователя в аргументах к программе, но тогда нужно уметь правильно запускать. Т.е. нужен установщик, который ярлык правильно настроит
    2. Отправлять вместе с программой файл конфигурации, из которого нужно читать имя пользователя.
    3. Скомпилировать с уже встроенным именем.

    Для последнего пункта можно сделать оптимизацию - весь проект (с логикой) хранить уже скопилированными, а при поступлении запроса компилировать exe. В него положить имя пользователя и просто скопировать готовые dll, а сам он просто будет прослойкой для самой программы.

    Также появилась идея о каком-нибудь шаблонном движке (по типу razor), который в потоковой обработке будет отправлять байты программы и в нужном месте подставит строку имени, но не знаю существует такое решение или нет (скорее нет)
    Ответ написан
  • Как передать данные из одного представления в другое?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Url.Action принимает аргумент object? values (последний). В него нужно передать параметры для обработчика MVC контроллера. Передавать в виде анонимного объекта.
    Для твоего случая это будет в виде:
    @foreach (var item in Model)
        {
            <tr onclick="location.href='@Url.Action("ViewOrder", "Home", new { id = item.Id })'">
                <td>@item.Id</td>
                <td>@item.CitySender</td>
                <td>@item.AdressSender</td>
                <td>@item.CityRecipient</td>
                <td>@item.AdressRecipient</td>
                <td>@item.Weight</td>
                <td>@item.Date</td>
            </tr>
        }

    Этот item.Id будет передаваться параметром в обработчик контроллера через параметр, который называется id.
    Например, в этотpublic IActionResult ViewOrder(int id)
    Ответ написан
    1 комментарий
  • Почему gRPC подменяет исключения?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    А откуда другой сервис знает, какие КЛАССЫ/ОБЪЕКТЫ есть в другом сервисе?
    Если нужно кидать такое-же исключение на сервисе клиенте, то нужно это исключение там и создать.

    А вообще, для своих типов исключений необходимо использовать GRPC_STATUS_UNKNOWN. В документации так и написано:
    Server threw an exception (or did something other than returning a status code to terminate the RPC)


    Решение только одно - в каждом сервисе писать свои обработчики таких исключений и свои классы исключений
    Ответ написан
    2 комментария
  • Как вызвать функцию на представление с контроллера в mvc паттерне?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Сделай колбэк
    class Ctrl
    {
        Action<int> _callback; 
        public void fun()
        {
             // ...
             _callback(res);
         }
    }
    
    public class View
    {
        void SendResult(int res)
        {
               LayoutUpdate(); 
        }
    }


    P.S. только в случае с GUI надо еще помнить, что обновления нужно делать в UI потоке
    Ответ написан
    Комментировать
  • Как создать приложение которое будет показывать погоду в любом городе на Win Forms?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    1. Создаешь свою базу данных городов (названия, расположения)
    2. Находишь API, которое по положению отдает погоду в нем
    3. Делаешь окно выбора города
    4. Когда пользователь выбрал город делаешь запрос на API (шаг 2) и показываешь результат

    На твое усмотрение:
    - Как будет выглядеть морда (UI)
    - Где хранится БД городов будет (загружаться во время старта, в txt/json файле, отдельная БД (sqlite, postgres))
    - Какой API погоды использовать
    Ответ написан
    9 комментариев
  • Как считать время у большого количества объектов?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Пусть у каждого объекта будет свой штамп времени - когда он протухает.
    В Update() проверяешь текущее время и время протухания - если превышено (и при этом предыдущее состояние не протухло), то меняешь вид/представление.
    Этакая машина состояний

    P.S. я не unity разраб., возможно во фреймворке уже есть готовые решения для такого
    Ответ написан
  • Почему C# не кроссплатформенный?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    С# работает на виртуальной архитектуре

    Правильнее говорить: имеет собственный байт код. Приложения .NET не запускаются в виртуальной машине! Они компилируются JIT'ом и просто могут взаимодействовать с платформой, но нет никакой ВМ (например, песочница как в JVM отсутствует - ты видишь обычный процесс.
    Почему так?

    Потому что C# (и .NET Framework в частности) был ориентирован для работы под Windows и там очень много специфичных для нее деталей есть (взять ту же концепцию COM объектов).
    Java изначально поддерживала другую стратегию + была поддержка Linux (на котором сидели энтузиасты), что в итоге вылилось в то, что эти самые энтузиасты полюбили Java и начали писать на ней везде (а для этого надо было иметь реализацию JVM под нужную платформу)
    Сейчас ситуация меняется: .NET есть под MacOS, Linux и Windows. Это не полная кроссплатформенность, но философия другая: мы будем поддерживать несколько платформ, но делать это качественно. Сейчас упор делается в Linux и веб в частности.
    Дополнительно:
    - Спецификация открытая и ничто не мешает реализовать под свои платформы. Взять тот же .net nanoFramework, mono, unity
    - Mono вышел в 2004 году, а значит еще с тех пор .NET был кроссплатформенным
    Ответ написан
    2 комментария
  • Как связать python flask сервер и код на C#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Здесь подойдет любой RPC фреймворк. В частности, рекомендую gRPC - довольно популярный и для твоего случая подходит хорошо:
    - Есть кодогенерация и для C# и для питона
    - Описание API не зависит от яп
    - Большое коммьюнити

    P.S. здесь подойдут и HTTP запросы. То что нужно долго ждать - ничего, подождет.
    GET запрос не обязательно должен выполняться моментально.
    Ответ написан
    Комментировать