В .NET Task ресурсите на нишката връщат ли се в pool-а, ако тя await-ва асинхронна операция?

+8 гласа
56 прегледа
попитан 2016 юни 17 в .NET от Nikoleta.V. (4,090 точки)
Имам TPL Task,който прави 2 неща. Първото е да извиква уеб сървис. Второто, вкарва данни в базата. Стигам до 20 task-а работещи в един момент, който правят едно и също. Всичко, което правят, е да извикват сървиса и да вкарват данни в базата.

Нов съм TPL на .NET. Правил съм само някои прецеси, които вървят в background-а и малко асинхронни уеб сървиси.

Извикването на уеб сървиса и писането в базата са процеси, които блокират Task-а, в който вървят. Доколкото знам, когато се ползват тези таскове, .NET управлява thread pool-а вместо нас. Така ли е?

Ще има ли повече свободни нишки в thread pool-а, ако направя тези 2 операции да се извикват с async и await, вместо да блокират работата?

Според моето разбиране, нишката не прави нищо докато изчаква блокирания таск и не връщат ресурсите си в thread pool-а. Но се чудя ако ги направя извикванията асинхронни дали основната нишка на таска ще може да върши друга работа, докато ги изчаква.

Правилно ли е това или е моя измислица?

Ползвам c# и .NET 4.0.

1 отговор

0 гласа
отговорени 2016 юни 21 от valeri.hristov (7,340 точки)

Ще има ли повече свободни нишки в thread pool-а, ако направя тези 2 операции да се извикват с async и await, вместо да блокират работата?

Зависи.

Когато използваш Task.Run, отзад класа Task използва ThreadPool да разтоварва работата като ползва нишка от ThreadPool-а.

Ако сървиса ти не предлага асинхронно API и използваш Task.Run да върши работата, пак ще блокираш нишката от threadpool-a да върши работа на IO, независимо от използването на async-await. В твоя случай и двете извиквания са блокиращи, което значи, че нишката пак ще бъде блокирана, тоест отговорът на въпроса е НЕ.

Ако сървиса и работата с базата имаха асинхронно API(което не използва допълнителни нишки да си върши работата), можеш да ползваш предимството на async-await, тъй като, когато await-ваш някое от тези извиквания(и не трябва да използваш Task.Run), текущата нишка ще върне контролна на тази, която ги е извикала, и може да се използва да върши друга работа. Ако са така нещата, отговорът е ДА.

Според моето разбиране, нишката не прави нищо докато изчаква блокирания таск и не връщат ресурсите си в thread pool-а. Но се чудя ако ги направя извикванията асинхронни дали основната нишка на таска ще може да върши друга работа, докато ги изчаква.

Правилно мислиш. Ако основната работа на threadpool-а е свързана с IO заявка, тогава тя през повечето време стои блокирана, докато заявката приключи.

Когато await-ваш Task, контролът се предава на извикващата нишка. Да предположим, че извикването от сървиса е REST, можеш да използваш HttpClient, което има асинхронни методи, които не използват нишки(GetAsync, PostAsync) и тогава можеш да ги await-неш, което ще освободи нишката и тя може да върши друга работа.

...