Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
часто в работе встаёт задача произвести какие-то действия в отдельном потоке и потом обработать результат в изначальном (обычно UI) потокеВ .NET для этого существовало средство и до async/await, это ThreadPool + SyncronizationContext. Именно последний отвечает за то, чтобы (опять же, цитата)
и когда UI поток освободится от своих текущих задач, он выполнит ProcessResult с данных полученными из второго потока. Просто применение async/await никакого переключения в исходный поток не делает
В .NET для этого существовало средство и до async/await, это ThreadPool + SyncronizationContext. Именно последний отвечает за то, чтобы (опять же, цитата)
Просто применение async/await никакого переключения в исходный поток не делает
private async void Handler(Params prms)
{
var r = await new Task(() => CalcSomething(prms););
ProcessResult(r);
}
private async void Handler(Params prms)
{
var r1 = await new Task<object>(() => CalsSomething())
ProcessResult(r1);
}
private async void Handler(Params prms)
{
var r2 = await Task.Run(() => CalsSomething());
ProcessResult(r2);
}
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.
Ну, в том виде, в котором вы привели код, оно вовсе не будет компилировать.
Если у входного потока был установлен SyncronizationContext, или в параметрах Task.Run был передан вот такой аргумент TaskScheduler.FromCurrentSynchronizationContext(), то по окончании исполнения CalсSomething исполнение неявного коллбека с ProcessResult будет добавлено в очередь к этому SyncronizationContext-у, и исполнено на входном потоке.
Если нет — исполнение ProcessResult будет выполнено на первом попавшемся треде, не обязательно UI.
Так вот, у WinForms у входного потока SyncronizationContext есть, поэтому ProcessResult отсылается исполняться на UI.
void Handler(const URL url) async_code
(
log_window+="Downloading "+url;
auto xml=ParseXML(await_async([&]{return Download(url);}));
log_window+="Downloading "+xml.GetValue("/update/text/url ");
result_window+=await_async([&]{return Download(xml.GetValue("/update/text/url "));});
)
task<int> t([]()
{
return 1;
}).then([](int n)
{
return n+1;
}).then([](int n)
{
return n+1;
}).then([](int n)
{
return n+1;
})
Вся реализация занимает какие-то жалкие 20 строчек простейшего кода!
Техника написания аналога await/async из C# для C++