Задать вопрос
Ответы пользователя по тегу Асинхронное программирование
  • C# Почему в ConsoleApp после await меняется поток, а в WinForms нет?

    Потому что в винформах свой synchronization context, а в консоли - стандартный.
    Почему в ConsoleApp после await меняется поток

    Вообще-то смена потока не гарантируется ;)

    Я знаю, что объекты интерфейса можно менять в единственном GUI-потоке.

    Вот ради этого контекст синхронизации и существует.

    CLR не нужно ничего понимать - ему заранее сообщается, что нужно использовать контекст синхронизации.
    Где именно это в недрах винформ происходит - не подскажу (надеюсь, меня дополнят)

    Если этого не сделать - используется стандартное поведение при котором разрешено менять потоки.
    Ответ написан
    Комментировать
  • Для чего нужна отмена задач, кроме таймаутов и каналов?

    В дополнение к предыдущему - случай с graceful shutdown, когда у тебя есть какой-то долгий процесс и в случае его завершения в середине нужно какие-то особые телодвижения совершить (сохранить результат куда нибудь в файлы, дождаться закрытия соединения итд.
    Ответ написан
    Комментировать
  • Можно ли упростить данный код (см. внутри), заменив ConcurrentBag list'ом и установив lock?

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


    1. Для каждого из файлов запусти по потоку (таске), каждый из которых пусть свой файл читает в поисках имеилов.
    2. Для записи в итоговый файл - заведи ещё 1 поток (таску).
    3. Коммуникацию между N читающими и 1 пишущим организуй через System.Threading.Channel

    Таким образом ты избавишься от ненужных блокировок и затрат на синхронизацию доступа к какому-то списку.

    UPD: в двух и больше файлах могут быть несколько одинаковых имэйлов и считывать мне надо именно первую копию имэйла из первого файла, где эта копия встретилась, если этот имэйл имеет несколько копий в разных файлах.

    UPD: тогда смотрим на количество данных.
    Если имеилов мало (по сравнению с количеством ОЗУ), то тогда можем прямо в памяти держать HashSet и проверять его в пишущем потоке.
    Если имеилов побольше - можем сделать HashSet не по самим и имеилам, а по их хешам.
    Если имеилов совсем много, то тогда можно записывать в отсортированную структуру данных на диск (двоичное дерево поиска например).

    UPD2:
    Для каждого из файлов запусти по потоку (таске), каждый из которых пусть свой файл читает в поисках имеилов.

    На самом деле можно попробовать запустить несколько потоков, разделив каждый файл ещё на N сегментов и назначив потокам эти сегменты. Плодить новые можно до тех пор, пока у тебя IO не кончится.
    Ответ написан
    1 комментарий
  • Стоит ли углубленно изучать многопоточность, асинхронное и паралельное программирование?

    Хочется ответить цитатой:
    Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!
    Ответ написан
    Комментировать
  • Как асинхронно (параллельно) скопировать файлы?

    1. у тебя обращение к стримам завёрнуто в using - они могут быть уничтожены до того как копирование завершится.
    Убери using var и сохраняй стримы вместе с таской. Диспозь уже после завершения таски
    2. Кажется, тебе может быть интересен Parallel Linq.
    Ответ написан
    Комментировать
  • Cинхрон или асинхрон?

    асинхрон
    Плюсы: экономия ресурсов
    Минусы: может немного сложнее
    Ответ написан
    Комментировать
  • Почему методы без await исполняются последовательно?

    почему считается, что методы без await выполняются гарантированно последовательно?

    Потому что так компилятор работает.
    Передача управления может произойти только там, где стоит await.
    => Если в async Task методе нет ни одного await, то метод будет выполняться синхронно от начала до конца, без передачи управления другим потокам
    Ответ написан
  • Стоит ли выносить выполнение синхронных методов в пулл потоков в контроллерах ASP NET Core?


    Асинхронных блоков, требующих использования await в методе нет.

    В таком случае это будет обычный синхронный метод, хоть и возвращающий таску.


    Встаёт вопрос - перевести ли выполнение этого метода в пулл потоков (через обёртывание в Task.Run) или оставить так как сейчас есть?

    Зависит от того, что именно ты там делаешь.
    Если есть работа с IO, то следует перейти на асинхронщину.

    Если долгие вычисления, то тогда да - есть смысл сделать Task.Run, чтобы не нагружать потоки из основного пула
    Ответ написан
    Комментировать
  • Как назначить асинхронный клиент для всего класса?

    Можно инициализировать клиент где-нибудь заранее, и прокинуть в конструктор класса уже готовый.

    Для удобства можно сделать статичный метод, который сделает всё сам
    Ответ написан
    Комментировать
  • Имеет ли смысл использовать асинхронные вызовы в консольных программах Don net core, если алгоритм обработки последователен?

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

    А ещё вместо WebRequest лучше использовать HttpClient
    Ответ написан
    1 комментарий
  • Как привести набор Task с разными возвращаемыми результатами к набору Task с результатами в виде общего интерфейса?

    Можно закостылить примерно так:
    serversStatisticRequests.Add(service.GetBasicStatus(server).ContinueWith(x => (IResponse) x.Result));
    serversStatisticRequests.Add(service.GetFullStatus(server).ContinueWith(x => (IResponse) x.Result));
    Ответ написан
    3 комментария
  • В чем роль Task.Run() и await в асинхронных методах?

    1.Task.Run нужен для запуска синхронных методов в тредпуле.
    2. Thread.Sleep использовать не рекомендуется, тк есть Task.Delay

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

    Читайте TAP.docx
    Ответ написан
    Комментировать
  • Как работают цепочки await в C#?

    Я много раз читал, что если await встречает Таск, который ещё не выполнен, то метод возвращает незавершённый таск и выполнение продолжается в вызывающем методе.

    Видимо, вы не дочитали, либо недопоняли.

    Возьму ваш первый пример, но немного его видоизмению, чтобы было понятнее, что проиходит:
    static async Task Method1Async()
            {
                Console.WriteLine("Starting Method1Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
                var task = Method2Async();
                await task; // До этой точки код выполняется синхронно (если таска ещё не готова)
                Console.WriteLine("End Method1Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
            }
            
            static async Task Method2Async()
            {
                Thread.Sleep(100); // Thread.Sleep - это блокирующая операция
                Console.WriteLine("Starting Method2Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
                await Task.Yield(); // До этой точки код выполняетя синхронно. Task.Yield освобождает поток всегда
                Console.WriteLine("End Method2Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
            }

    Подробнее можете узнать, если загуглите TAP.docx
    Ответ написан
    Комментировать
  • Как правильно распараллелить?

    vabka
    @vabka Куратор тега Rust
    При http запросах всё будет упираться в ввод-вывод, так что очень вероятно, что сам тор медленно работает - тогда лучше наоборот урегулировать количество одновременных запросов.

    Как именно это сделать не подскажу, тк в rust разбираюсь не очень хорошо.
    Ответ написан
    Комментировать