Подтвердить что ты не робот

Является Async/Await с помощью Task.Run запускает новый поток асинхронно?

Я прочитал много статей и все еще не могу понять эту часть.

Рассмотрим этот код:

    private async void button1_Click(object sender, EventArgs e)
    {
        await Dosomething();
    }

    private async Task<string> Dosomething()
    {
        await Task.Run((() => "Do Work"));
        return "I am done";
    }

Первый вопрос:

Когда я нажимаю кнопку, он вызывается DoSomething и ждет Task, который создает Thread из потока thread, вызывая Task.Run(если я не ошибаюсь), и все это выполняется асинхронно. Итак, я добился создания потока, который выполняет мою работу, но делает это асинхронно? Но учтите, что мне не нужен какой-либо результат, я просто хочу, чтобы работа была выполнена без получения какого-либо результата, действительно ли нужно использовать async/await, и если да, то как?

Второй вопрос:

При запуске потока асинхронно, как это работает? Он работает на основном пользовательском интерфейсе, но на отдельном потоке или работает на отдельном потоке и раздельно асинхронно внутри этого метода? Я, возможно, испортил разницу между асинхронными методами и потоками, поэтому, пожалуйста, расскажите мне обо мне.

4b9b3361

Ответ 1

  • Цель создания методов Async заключается в том, что вы можете ожидать их позже. Как будто "Я собираюсь положить эту воду на кипение, закончить приготовление остальной части моих ингредиентов супа, а затем вернуться в горшок и ждать, пока вода закончит кипение, чтобы я мог приготовить обед". Вы начинаете кипение воды, которое оно делает асинхронно, в то время как вы делаете другие вещи, но в конечном итоге вы должны остановиться и дождаться его. Если вы хотите "стрелять и забыть", тогда не нужны Async и Await.

Простейший способ сделать огонь и забыть метод в С#?

  1. Запуск новой задачи приостанавливает выполнение этой задачи в потоке threadpool. Темы выполняются в контексте процесса (например, исполняемый файл, который запускает ваше приложение). Если это веб-приложение, работающее под IIS, то этот поток создается в контексте рабочего процесса IIS. Этот поток выполняется отдельно от основного потока выполнения, поэтому он отключается и выполняет свою работу независимо от того, что делает ваш основной поток выполнения, и в то же время ваш основной поток выполнения перемещается с его собственной работой.

Ответ 2

Тип Task<TResult> требует возврата TResult из вашей задачи. Если вам нечего возвращать, вы можете вместо этого использовать Task (что, кстати, является базовым классом Task<TResult>).

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

Ответ 3

1

Там большая разница, если вы не await Task или вы await it:

  • Дело в том, что вы не await it: DoSomething вызывается, но следующее предложение выполняется, пока DoSomething Task не завершено.

  • Вы вызываете await it: DoSomething и следующее предложение выполняется после завершения DoSomething Task.

Таким образом, необходимость async/await будет зависеть от того, как вы хотите вызывать DoSomething: если вы не await, это похоже на вызов огня и забудьте способ.

2

Работает ли он на основном пользовательском интерфейсе, но на отдельном потоке или работает на отдельной нити и отдельно асинхронно внутри метод?

Асинхронный код иногда означает другой поток (см. этот Q & A Асинхронный и многопоточность - есть разница?). То есть, если код выполняется в отдельном потоке из пользовательского интерфейса, или он позволяет продолжить обработку потока пользовательского интерфейса во время его возобновления, это хорошо, потому что петля пользовательского интерфейса все еще может обновлять экран, в то время как другие задачи выполняются в параллельной без замораживания пользовательского интерфейса.

Асинхронный метод (т.е. метод async) является синтаксическим сахаром, чтобы сообщить компилятору, что операторы await следует рассматривать как конечный автомат. Компилятор С# превращает ваш код async/await в конечный автомат, где после ожидаемого кода выполняется код, ожидающий результата Task.

Интересный Q & As

Возможно, вам захочется просмотреть эти другие Q & As:

OP сказал...

[...] Но означает ли это, что "async/await" сработает поток и Task.Run также запускает нить или они оба являются одним и тем же потоком?

Использование async - await не означает "Я создаю поток". Это просто синтаксический сахар, чтобы воплотить его в элегантном стиле. Задача может быть или не быть нитью. Например, Task.FromResult(true) создает поддельную задачу, чтобы иметь возможность реализовать метод async без необходимости создания потока:

public Task<bool> SomeAsync()
{
    // This way, this method either decides if its code is asynchronous or 
    // synchronous, but the caller can await it anyway!
    return Task.FromResult(true);
}