@vivaldistone

Асинхронность и её работа?

Всем здравствуйте, наткнулся на такой момент, копая внутрь асихронности. И читая статью Стивена Клири про Task не есть поток ( https://blog.stephencleary.com/2013/11/there-is-no... ). В статье достаточно материала, который не совсем понятен для меня, назрели вопросы.
private async void Button_Click(object sender, RoutedEventArgs e)
{
byte[] data = ...
ИСТИННАЯ АСИНХРОННОСТЬ
await myDevice.WriteAsync(data, 0, data.Length);
}
В частности как я понял, мы не можем воспроизвести операцию записи в файловый поток аналогичный дефолтному из стандартной библиотеки. Запустив его через Task.Run(), мы привяжем таску записи файл к новому потоку:
private static async Task ReadFile() - здесь операция чтения, сути не меняет.
{
await Task.Run(()=> using (FileStream fs=new FileStream("index.txt", FileMode.Open))
{
fs.Read(...);
}
}
Собственно воспроизвести мы по-настоящему асинхронный метод чтения/записи не в состоянии, как я понял отслеживая количество задействованных потоков.
Собственно вопрос номер 1. То что async метод из стандартной библиотеки не выделяет на задачу поток, это результат работы технологии DMA? Либо это просто уровень ниже, где уже не оперируют понятиями потока как таковыми. Процессор ведь постоянно участвует в работе копирования из оперативной памяти на жесткий диск либо обратное. Просто эта операция на занимает поток(см.ниже)
2 вопрос. Отдача запросов и получение данных на сокет, как пример HttpClient
HttpClient _client=new HttpClient();
var rezult=_client.GetAsync("https://google.com");
Внутри него таска тоже не требует отдельного потока под выполнение задачи под Get?
И если очевидно это так, то тут мне понятен профит от асихронщинности, хотя могу ошибаться, профит за счёт того, что под задачу не задействуется отдельный поток, мы его не заимствуем, await вернёт поток в тредпул пока ждёт задачу, там уже в зависимости от контекста решает, что делать. Как следствие больше потоков остаётся свободными под те же наши запросы/ответы, операции чтения/записи.
А если под задачу всё же выделяется отдельный поток, за счёт чего профит достигается, ну мы и тредпулом можем отдельный поток выделить под нашу "задачу", что она Task.Run выполнится, что тредпулом, не понимаю в чём преимущество.
  • Вопрос задан
  • 63 просмотра
Пригласить эксперта
Ответы на вопрос 1
@GLeBaTi
TaskScheduler - пул потоков для task-ов
SynchronizationContext - содержит свой поток и данные, который не используется TaskScheduler-ом
Task.Run - достаёт свободный поток из TaskScheduler.
await Task.Run - запоминает текущий SynchronizationContext (если есть), останавливает текущую задачу, запускает другую задачу.

Когда дочерняя задача завершится, наша задача продолжит выполнение в:
- потоке из запомненного контекста синхронизации
- потоке из TaskScheduler.

Т.е. async/await нужен для возврата потока выполнения к контексту синхронизации, если он есть. И не использовать всякие BeginInvoke
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы