Позвольте мне просто написать все это как ответ. Вы смешиваете две связанные, но в конечном счете отдельные концепции (к счастью - вот почему вы можете воспользоваться различием). Обратите внимание, что это мои определения понятий - вы услышите тонны разных имен для одних и тех же вещей и наоборот.
Asynchronicity о нарушении наложенной синхронности операций (т.е. op 1 ждет op 2, который ждет op 3, который ждет op 4 ...). Для меня это более общая концепция, но в настоящее время она чаще используется для обозначения того, что я называю «присущей асинхронности», т. Е. сам алгоритм асинхронен, и мы используем только синхронное программирование, потому что нам нужно (и спасибо await
и async
, нам больше не нужно, yay!).
Основная мысль здесь ожидания. Я ничего не могу сделать в CPU, потому что жду результата операции ввода-вывода. Такое асинхронное программирование основано на мысли, что асинхронные операции почти бесплатны - они связаны с I/O, а не с ЦП.
Параллелизм - это особый вид общей асинхронности, в которой операции не в основном ждут друг друга. Другими словами, я не жду, я работаю .Если у меня есть четыре ядра процессора, я в идеале могу использовать четыре вычислительных потока для такого вида обработки - в идеальном мире мой алгоритм будет линейно масштабироваться с количеством доступных ядер.
С асинхронностью (ожидания), используя больше потоков, улучшит кажущуюся скорость независимо от количества доступных логических ядер. Это связано с тем, что в 99% случаев код фактически не работает, он просто ждет.
С параллелизмом (), используя больше потоков, напрямую привязывается к количеству доступных рабочих сердечников.
Линии размыты a лот. Это из-за того, что вы, возможно, даже не знаете, происходит, например, процессор (и компьютер в целом) невероятно асинхронен сам по себе - видимая синхронность, которую он показывает, только там, чтобы вы могли синхронно писать код; все оптимизации и асинхронность ограничены тем, что на выходе все снова синхронно. Если ЦП должен был ждать данные из памяти каждый раз, когда вы делаете i ++
, неважно, работал ли ваш процессор на частоте 3 ГГц или 100 МГц. Ваш замечательный 3 ГГц процессор будет сидеть там без дела в 99% случаев.
С учетом этого ваши расчетные задачи связаны с ЦП. Они должны выполняться с использованием параллелизма, потому что они выполняют работу. С другой стороны, UI связан с I/O, и он должен использовать асинхронный код.
В действительности, все ваши методы async Calculate
делает это, что он маскирует тот факт, что это не фактически неотъемлемо асинхронный. Вместо этого вы хотите, чтобы запускал асинхронно с I/O.
Другими словами, это не метод Calculate
, который является асинхронным. Это пользовательский интерфейс, который хочет, чтобы это выполнялось асинхронно для себя. Удалите все, что Task.Run
беспорядок оттуда, он не принадлежит.
Что делать дальше? Это зависит от вашего варианта использования. В принципе, существует два сценария:
Вы хотите, чтобы задачи всегда выполнялись всегда в фоновом режиме от начала и до конца. В этом случае просто создайте поток для каждого из них и вообще не используйте Task
. Вы также можете изучить некоторые параметры, такие как очередь производителей-потребителей и т. Д., Чтобы оптимизировать фактическое время выполнения различных возможных задач расчета. Фактическая реализация довольно тесно связана с тем, что вы на самом деле обрабатываете.
Или вы хотите запустить задачу над действием пользовательского интерфейса, а затем работать с результирующими значениями в методе пользовательского интерфейса, который запустил их , когда результаты будут готовы.. В этом случае, await
наконец приходит играть:
private btn_Click(object sender, EventArgs e)
{
var result = await Task.Run(Calculate);
// Do some (little) work with the result once we get it
tbxResult.Text = result;
}
async
ключевое слово на самом деле не имеет места в коде вообще.
Надеюсь, теперь это более понятно, не стесняйтесь задавать больше вопросов.
Вы можете добавить код, который вы используете до сих пор. Поскольку многопоточность в C#/WPF может быть выполнена различными способами, и вы уже говорите о двух разных механизмах (Задачи/Параллельные). – woutervs
Трудно дать вам что-либо, не видя, как ваш код в настоящее время структурирован. Мы можем делать только предположения. Случайно ожидая задачи по задержке, бессмысленно, хотя .. все это будет продолжаться синхронно. –
Также, какая работа есть? Связаны ли рабочие элементы? Действительно ли они на 100% связаны с процессором, или есть ли активность ввода-вывода, вызывающая задержки? Что «висит»? Пользовательский интерфейс? Или только некоторые из задач получают свою «справедливую» долю в ЦП? Вы хотите асинхронность или параллелизм? «Задача» - для асинхронности, * не * параллельности, т. Е. он предназначен для того, чтобы вы могли выполнять много операций, не связанных с ЦП, «одновременно», без дополнительных затрат на дополнительные потоки. – Luaan