Здравствуйте, m2user, Вы писали:
M>Если же речь о коде, где нужно распараллелить операции, которые до этого выполнялись последовательно, то такой код понадобится раздробить на Runnable/Callable составляющие (функции или лямбды), попутно переписывая работу с переменными на стеке, возвратом результата, обработкой исключений.
M>Я утверждаю, что для такого кода:
M>1) по объему работы это не проще перевода на await/async
На порядок проще.
Вот у тебя код:
var details1 = someBigDao.complexBusinessLogicWhichDoesALotOfSQLQueriesSynchronously();//работает 20 секунд
var details2 = someService.itGoesToNetworkAndDownloadsDataUsingSomeCrazySoapFramework();//работает 30 секунд
return compbine(details1, details2);//общее время 50 секунд
В шарпе если ты такой код завернёшь в async, то толку никакого, т.к. первый же sql.execute() полезет синхронно в сокет и заблокирует твой async пока тот ждёт ответа от sql-сервера. Чтобы эти два метода запустить и чтобы они работали одновременно — тебе нужно запустить два честных треда.
Либо переписать всё на async-методы, чтобы они протаскивали Task по всему коду:
Т.е. если где-то внутре есть код типа
Result complexBusinessLogicWhichDoesALotOfSQLQueriesSynchronously()
{
var r1 = sql.query(aaa);
var r2 = sql.query(bbb);
var r3 = sql.query(ccc);
var r4 = anotherStuffWhichDoesSql(r2);
return new Result(....);
}
то каждый sql.query тебе нужно придётся оборачивать в async и так по всей глубине стека.
С виртуальными тредами — ты просто пускаешь эти два метода и они работают параллельно:
var details1 = executor.submit(() -> someDao.complexBusinessLogicWhichDoesALotOfSQLQueriesSynchronously());
var details2 = executor.submit(() -> someService.downloadDataUsingSomeCrazySoapFramework()));
return combine(details1.join(), details2.join());//общее время 30 секунд
Всё. Ничего внутри someDao или someService менять не нужно.
M>2) await/async позволил бы писать более "плоский" код (меньше вложенных блоков кода)
Не позволил бы. Или показывай что ты имеешь в виду.
M>Executors.newVirtualThreadPerTaskExecutor, которыей я упомянул в соседнем сообщении, частично облегчает ситуацию — с возвратом результата Callable и пробросом исключения (в виде ExecutionException)
Проброс исключений, callable и прочее не имеет никакого отношения к сабжу.