Урок 10. Получение результатов от параллельных задач C#


В десятой части учебника по параллельному программированию в .NET рассматривается универсальный класс Task<T>. Это подкласс класса Task, рассмотренного ранее, который позволяет генерировать результат и получать к нему доступ из вызывающего потока.

Результаты выполнения задач

До сих пор при рассмотрении параллельных задач мы рассматривали класс Task. Он позволяет выполнять делегат действия с возможностью параллелизма. Делегат может получить доступ к переменным, которые находятся вне его области действия, чтобы взаимодействовать с основным потоком выполнения или с другими задачами, позволяя имитировать возвращаемое значение. Однако для более элегантной генерации возвращаемых значений доступен альтернативный класс задач.

Универсальный класс Task<T> наследует большую часть своей функциональности от своего не-универсального аналога. Задачи создаются с помощью делегата, часто лямбда-выражения, запускаются с помощью метода Start и выполняются параллельно там, где это эффективно. Ключевое отличие заключается в том, что лямбда-выражение возвращает значение типа, определенного параметром Type задачи. Это возвращаемое значение можно получить, прочитав свойство результата задачи.

Класс Task<T> находится в System.Threading.Tasks пространства имен, так что чтобы упростить примеры, добавьте следующую директиву using:

using System.Threading.Tasks;
Синхронизация

Как и в других параллельных и многопоточных сценариях, требуется синхронизация. В этом случае необходимо следить за тем, чтобы результат параллельной задачи не считывался до ее постановки. К счастью, параллельная библиотека задач позаботится об этом за вас. Если вы попытаетесь прочитать результат слишком рано, текущий поток будет заблокирован до завершения выполнения задачи. Это то же самое, что вызвать метод Wait вручную перед чтением результата.

В следующем примере показано использование параллельной задачи с возвращаемым значением. Здесь выполняется длительный расчет, и возвращаемый результат извлекается из свойства Result. Вы можете видеть, что основной поток блокируется до тех пор, пока параллельное вычисление не завершится, чтобы убедиться, что получено правильное значение.

public class Program
{
	public static void Main()
	{
	Task<long> taskWithResult = new Task<long>(() =>
{
    long total = 0;
    for (int i = 1; i < 500000; i++)  // отрегулируйте этот цикл в соответствии с
    {                                        // с произврдительностью скорость  вашего компьютера
        total += i;
    }
    return total;
});
taskWithResult.Start();
 
Console.WriteLine("Result = {0}", taskWithResult.Result);
 
taskWithResult.Dispose();
 
/* Вывод
 
esult = 124999750000
 
*/
	}
}
Методы Wait, WaitAll и WaitAny все еще можно использовать, когда вы хотите иметь больше контроля над синхронизацией. Ниже приведены две аналогичные параллельные задачи, которые выполняются и ожидаются с помощью метода WaitAll перед использованием их результатов.

public class Program
{
	public static void Main()
	{
	Task<long> taskWithResult = new Task<long>(() =>
{
    long total = 0;
    for (int i = 1; i < 1000000000; i++)
    {
        total += i;
    }
    return total;
});
 
Task<long> taskWithResult2 = new Task<long>(() =>
{
    long total = 0;
    for (int i = 1; i < 8000000; i++)
    {
        total += i;
    }
    return total;
});
 
taskWithResult.Start();
taskWithResult2.Start();
Task.WaitAll(taskWithResult, taskWithResult2);
 
Console.WriteLine("Results = {0}, {1}", taskWithResult.Result, taskWithResult2.Result);
 
taskWithResult.Dispose();
taskWithResult2.Dispose();
 
/* OUTPUT
 
Results = 499999999500000000, 31999996000000
 
*/
	}
}
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, параллельное программирование, си шарп, tasks




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



Урок 7. Простая отправка email в Laravel через smtp
Урок 21. Функции сравнения строк C#
Методы array_filter(), array_map() и array_reduce() в PHP с примерами