Ответы пользователя по тегу C#
  • Работа со звуком в C#/.NET?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    NAudio
    Ответ написан
    Комментировать
  • Как вставлять текст из буфера обмена в Unity?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Посмотрите на TextCopy
    Ответ написан
    Комментировать
  • Как записать ошибку в файл C#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Играю в угадайку. Наверное вы хотите это:
    using System;
    using System.IO;
    
    class Program {
        static void Main() {
            System.AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
            throw new Exception("СМЭРТЬ");
        }
        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) {
            File.WriteAllText("UnhandlerError.log", e.ExceptionObject.ToString());
            Environment.Exit(1);
        }
    }
    Ответ написан
  • Как отыскать индекс значения в массиве?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Уж больно мне не нравится вариант от BasiC2k, по тому решил написать свой:
    1. Чуть более компактный в плане памяти и количества кода, если нужно найти индекс один раз. + С проверкой, на отсутствие слова.
    var array = new[] { "Картоновый человек", "Морковка белая", "секретный специалист " };
    
    Console.WriteLine(FindIndexOfWord(array, "картоновый")); // 0
    Console.WriteLine(FindIndexOfWord(array, "Бомбастер")); // -1
    Console.WriteLine(FindIndexOfWord(array, "Специалист")); // 2
    
    // В 1 проход. Если не нравится linq - можно одной кнопкой переписать на циклы и получится почти zero-allocation код.
    static int FindIndexOfWord(string[] array, string word) => 
        array
          .Select((str, i) => (str.Split(' '), i))
          .Where(x => x.Item1.Any(w => w.Equals(word, StringComparison.OrdinalIgnoreCase)))
          .Select(x => x.Item2)
          .Cast<int?>()
          .FirstOrDefault() ?? -1;

    2. Более быстрый, если нужно искать данные много раз и в больших массивах:
    var array = new[] { "Картоновый человек", "Морковка белая", "секретный специалист " };
    
    var index = new WordIndex(array);
    Console.WriteLine(index.Find("картоновый")); //0
    Console.WriteLine(index.Find("чикибамбони")); //-1;
    
    // Поиск элемента в словаре по ключу выполняется за константное время, так что если нужно делать это часто и на больших массивах, то выгоднее 1 раз всё проиндексировать.
    class WordIndex {
       private readonly Dictionary<string, int> _cache;
       
       public WordIndex(IEnumerable<string> seq) {
         _cache = new Dictionary<string, int>();
         var i = 0;
         foreach(var str in seq) {
           foreach(var word in str.Split(' ')) {
             var key = word.ToUpperInvariant();
             if(!_cache.ContainsKey(key)) {
               _cache.Add(key, i);
             }
           }
           i++;
         }
       }
       
       public int Find(string word) =>
         _cache.TryGetValue(word.ToUpperInvariant(), out var value)
           ? value
           : -1;
    }
    Ответ написан
    2 комментария
  • Передать в keybd_event клавиши, выходящие за диапазон byte?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    https://docs.microsoft.com/en-us/windows/win32/inp...
    Control - 0x11
    LControl - 0xA2
    RControl - 0xA3

    System.Windows.Forms.Keys - это не virtual key code.

    Когда работаете с виндовыми библиотеками - всегда обращайте внимание на микрософтовскую документацию, там всё написано.
    Ответ написан
    1 комментарий
  • Где находятся журнальные сообщения в бд ef core?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    1. В DbContext можно включить логирование всех SQL-запросов
    2. Чтобы посмотреть данные в БД - используйте SSMS
    Ответ написан
  • Как добавить значение struct в list in list?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    var listOfLists = new List<List<int>>();
    for(var i=0; i<10; i++) {
      var list = new List<int>();
      for(var j=0; j<10; j++) {
        var item = j;
        list.Add(item);
      }
      listOfLists.Add(list);
    }
    Ответ написан
    Комментировать
  • Как избавиться от ошибки в сложении чисел на C#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Очевидно, что округлять.
    Или детектить тип и делать целочисленное сложение, если дробной части нет
    Ответ написан
  • Как парвильно обратиться к контроллеру, передав в качестве параметра массив?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Емнип, при использовании convention-based маршрутизации, префис Get у имени метода отбрасывается.
    Тоесть путь должен получиться такой:
    http://localhost:5000/api/Rtb/Param?ids=1&ids=2

    P.S. Если удалить первое действие, то все выполняется как надо

    Видимо коллизия, тк у вас они оба отмечены HttpGet - значит оба будут на одном пути. А FromQuery параметры опциональны - вот он и не может выбрать один из них (о чём написано в логе, скорее всего)

    Уберите первое действие и оставьте только вариант с параметром
    Ответ написан
  • В чем роль Task.Run() и await в асинхронных методах?

    vabka
    @vabka Куратор тега .NET
    Токсичный шарпист
    1.Task.Run нужен для запуска синхронных методов в тредпуле.
    2. Thread.Sleep использовать не рекомендуется, тк есть Task.Delay

    Второй пример действительно похож на опечатку.
    Оба примера плохие: Например если в первом методе убрать await Task.Run, то Thread.Sleep займёт вызывающий поток

    Читайте TAP.docx
    Ответ написан
    Комментировать
  • Как лучше всего использовать Electron и c#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Комментировать
  • Как лучше всего сохранять данные?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Мб использовать фаловую бд, типа sqlite?
    Или просто в текстовые файлы.
    Ну это если надо хранить состояние после закрытия приложения.
    Хз, как вы могли до такого не додуматься, если у вас действительно много опыта
    Ответ написан
    Комментировать
  • Как правильно публиковать net core приложение на linux?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Можно ли автоматизировать процесс?

    Одно слово - systemd.
    Загружаете файлы на сервер во временную папку
    копируете их из временной папки в папку с екзешниками
    systemctl ... restart

    Можно ли как-то в visual studio сделать чтобы перед публикацией она подключилась по SHH, вошла под root, остановила сервис, опубликовала файлы и вновь запустила сервис?

    Visual studio тут не нужна, как и FTP - всё можно сделать одним bash / powershell скриптом. Загружать файлы рекомендую через scp или через rsync.

    И дополнительный вопрос, как сделать чтобы остановка сервиса не нарушила работу приложения?

    Завести два сервера и делать сине-зелёный деплой.
    Ну или два экземпляра сервиса.
    Или если сервис остановится в процессе выполнение участка коды, который нельзя прерывать

    У Generic host есть механизм graceful shutdown.
    Если приходит сигнал на остановку - критичный сервис может это обработать и нормально доделать свои дела (ну или нормально отменить всё) перед выключением.

    Для сложных сценариев деплоя есть ещё Octopus и всякие докеры/кубернетесы. (но если контейнеры не используются, или не хочется оверинжинирить с кубером - можно обойтись одним только октопусом)
    Ответ написан
    1 комментарий
  • Как разделить большой файл?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    using System;
    using System.IO;
    using System.Linq;
    
    var command = args[0];
    if (command == "split")
    {
       // Чтобы разбить файл, нужно передать команду split ./path/to/file/test
        // В итоге в текущей папке появится папка result с чанками по 2кб, которые будут называться, как оригинальный файл, но с номером на конце.
       // например ./result/test1
       // ./result/test2 итд
        var filePath = args[1];
        const int chunkSize = 2 * 1024; // 2 KB
        await using var src = File.OpenRead(filePath);
        var fileName = Path.GetFileName(filePath);
        var chunkNo = 0;
        var buffer = new Memory<byte>(new byte[1024]); // 1 KB buffer
    
        Directory.CreateDirectory("result");
        var bytesInChunkWritten = 0;
        var currentChunk = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), "result", fileName + chunkNo));
    
        while (true)
        {
            var bytesRead = await src.ReadAsync(buffer);
            await currentChunk.WriteAsync(buffer[..bytesRead]);
            if (bytesRead < buffer.Length)
                break;
            bytesInChunkWritten += bytesRead;
            if (bytesInChunkWritten >= chunkSize)
            {
                await currentChunk.DisposeAsync();
                chunkNo += 1;
                currentChunk = File.OpenWrite(Path.Combine(Directory.GetCurrentDirectory(), "result", fileName + chunkNo));
                bytesInChunkWritten = 0;
            }
        }
    }
    else if (command == "merge")
    {
        // Чтобы склеить файлы - нужно передать команду merge с путём к папке со всеми чанками и оригинальным названием файла
       // Например если оригинальный файл назывался test, то нужно дать команду merge ./result/test
      // В итоге в папке ./result появится оригнальный файл test
        var filePath = Path.GetFullPath(args[1]);
        var dir = Path.GetDirectoryName(filePath);
        var fileName = Path.GetFileName(filePath);
        // Сортируем все чанки в правильном порядке
        var chunks = Directory.GetFiles(dir!, fileName + "*")
            .Where(x => x.Length > filePath.Length)
            .OrderBy(x => int.Parse(x[filePath.Length..]));
        // Создаём файл
        var dest = File.OpenWrite(Path.Combine(dir, fileName));
        // Перекладываем всё в него
        foreach (var chunk in chunks)
        {
            await using var file = File.OpenRead(chunk);
            await file.CopyToAsync(dest);
        }
    }

    Накидал за пару минут пример, который вполне успешно делит файлы на куски по 2кб и склеивает обратно.
    Код не идеален, да и сам алгоритм можно улучшить - например добавить хэш оригинального файла, чтобы можно было проверить целостность, или разбивать на произвольные куски.
    Ответ написан
    Комментировать
  • Можно ли сгенерировать отчеты Allure для xUnit?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Видимо речь про это: https://github.com/TinkoffCreditSystems/Allure.XUnit
    Ответ написан
    Комментировать
  • Как использовать конструктор или же дизайнер в VS code C#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Никак. Дизайнер форм есть (по крайней мере был раньше) в Monodevelop, но только для mono, тк Winforms только для винды.

    Если хотите кроссплатформенную технологию, то берите Avalonia, вроде у неё есть браузерный превьюер
    Ответ написан
    Комментировать
  • Как спарсить строку вида ключ=значение?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Размером от 700 до 2000

    Это ещё не очень большая.
    Судя по примеру текста - там есть переносы строк.
    Можно сделать так:
    var text = @"pr_fp=ea4b83cce35fe5dc744ef485372f1cdeec8862e546fc4ce353e309b5a88351d9
    wasm=b1a91e0252cc91a33cb489f2f0ca5b06
    rcid=111a5116-d8cd-405d-9c74-7776cba81515
    ";
    var dict = text
        .Split(new []{'\n', '\r'}, StringSplitOptions.RemoveEmptyEntries)
        .Select(x=>x.Split('=', 2))
        .ToDictionary(x=>x[0], x=>x[1]);
    var wasm = dict["wasm"];
    Console.WriteLine(wasm); //b1a91e0252cc91a33cb489f2f0ca5b06
    Ответ написан
    7 комментариев
  • Как правильно использовать класс Startup для чтения Json и использования данных из него?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    1. IConfiguration резолвится извне, так что эти строки не нужны:
    Configuration = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .AddEnvironmentVariables()
                    .Build();

    Надо только конструктор для этого добавить:
    public Startup(IConfiguration configuration) =>
                Configuration = configuration;
    
            public IConfiguration Configuration { get; }

    2. Не нужно собирать контейнер. Просто вызывай:
    Configuration.Get<AppSettings>();
    Ответ написан
    1 комментарий
  • Как на C#(Windows Forms) можно масштабировать векторный (в моем случае .eps) файл?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Комментировать
  • Asp.net core webapi - sync/async методы контроллера?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    А если в коде контроллера нет вызова асинхронных методов, будет ли какая-то разница?

    Если асинхронных вызовов нет, то нет смысла делать метод контроллера асинхронным.
    Или может быть имеет смысл этот код без асинхронных вызовов обернуть в таск и авейтить его, сделав метод контроллера асинхронным?

    Нет. Перед и после контроллера есть ещё куча middleware и Action / Result фильтров, которые и так асинхронные, так что вы и так получите все преимущества асинхронного IO при работе с HTTP

    Читайте ASP.NET Core Performance Best Practices
    Самое главное:

    Do not:
    • Block asynchronous execution by calling Task.Wait or Task.Result.
    • Acquire locks in common code paths. ASP.NET Core apps are most performant when architected to run code in parallel.
    • Call Task.Run and immediately await it. ASP.NET Core already runs app code on normal Thread Pool threads, so calling Task.Run only results in extra unnecessary Thread Pool scheduling. Even if the scheduled code would block a thread, Task.Run does not prevent that.

    Ответ написан
    Комментировать