Как смоделировать дорогую операцию с асинхронностью? - PullRequest
0 голосов
/ 23 января 2019

Является ли код с этой страницы действительно лучшим способом для имитации длительной задачи?

Консольное приложение, над которым я работал, довольно простое и, кажется, работает просто отлично.

Я не уверен, что смогу поменять DoExpensiveCalculation на метод Async, например GetStringAsync с HttpClient без проблем.

using System;
using System.Threading.Tasks;

namespace ExpensiveAsync
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("started");

            var t = CalculateResult("stuff and that");

            Console.WriteLine("press return");
            Console.ReadLine();
        }

        public static async Task<string> CalculateResult(string data)
        {
            // This queues up the work on the threadpool.
            var expensiveResultTask = Task.Run(() => DoExpensiveCalculation(data));

            // Note that at this point, you can do some other work concurrently,
            // as CalculateResult() is still executing!

            Console.WriteLine("concurrent");

            // Execution of CalculateResult is yielded here!
            var result = await expensiveResultTask; // CalculateResult returns the Task object here

            Console.WriteLine("synchronous"); // this code runs once the DoExpensiveCalculation method has finished

            return result;
        }

        public static string DoExpensiveCalculation(string data)
        {
            var completionTime = DateTime.Now.AddSeconds(3);

            Console.WriteLine("begin");

            while (DateTime.Now < completionTime) ;

            Console.WriteLine("finish");

            return data;
        }
    }
}

1 Ответ

0 голосов
/ 24 января 2019

Структура кода подразумевает, что DoExpensiveCalculation является операцией, связанной с процессором. Если вы хотите отключить связанную с процессором операцию без загрузки процессора, Thread.Sleep является подходящей опцией.

Я не уверен, смогу ли я без проблем поменять DoExoyCalculation на метод Async, такой как GetStringAsync, из HttpClient.

Ну, это совсем другое. GetStringAsync не является операцией, связанной с процессором; это операция ввода-вывода.

Операции, связанные с вводом / выводом, являются естественно асинхронными и могут использоваться непосредственно с async и await. Связанные с процессором операции, естественно, являются синхронными, поэтому иногда вам нужно использовать Task.Run. «Иногда» в этом случае обычно означает «когда вы в потоке пользовательского интерфейса», так что пользовательский интерфейс не останавливается во время выполнения операции с привязкой к процессору. Когда вы оборачиваете связанную с процессором операцию в Task.Run, вы можете обрабатывать ее как асинхронную, то есть await, извлекая ее из потока пользовательского интерфейса.

Ваш пример кода представляет собой консольное приложение, где использование Task.Run обычно не требуется. Консольные приложения обычно запускают любой код, который им необходим для запуска и выхода; в большинстве случаев нет интерфейса пользователя, который нужно поддерживать адаптивным, и, следовательно, нет необходимости в Task.Run.

...