В основе библиотеки
TPL лежит концепция
задач.
Каждая
задача описывает отдельную продолжительную операцию.
Задача представлена классом
Task
class Task упрощает написание кода для создания новых потоков.
Поэтому начиная с .NET 4.0. рекомендуется использовать именно класс
Task для создания многопоточных приложений.
public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
{
// конструктор
public Task(Action action);
...
// методы Run
public static Task Run(Action action);
public static Task<T> Run<T>(Func<T> function);
...
// методы Start
public void Start();
public void Start(TaskScheduler scheduler);
...
// factory
public static TaskFactory Factory { get; }
}
Класс
Task наследуется от интерфейса
C#
public interface IAsyncResult
{
bool IsCompleted { get; }
WaitHandle AsyncWaitHandle { get; }
object AsyncState { get; }
bool CompletedSynchronously { get; }
}
C#
Создаем новое C# консольное приложение... и напишем код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// вариант 1 (запускаем задачу в отдельном потоке)
Task t1 = Task.Run(() => Console.WriteLine("Hello1"));
// вариант 2 (запускаем задачу в отдельном потоке)
Task<int> t2 = Task.Run(() => Math.Max(10, 20));
int myMax = t2.Result;
// вариант 3 (запускаем задачу в отдельном потоке)
Task t3 = new Task(() => Console.WriteLine("Hello2"));
t3.Start();
// вариант 4 (запускаем задачу в отдельном потоке)
Task t4 = Task.Factory.StartNew(() => Console.WriteLine("Hello3"));
// ждем нажатия клавиши
Console.ReadLine();
}
}
}
Метод
Task.Run исполняет переданный ему делегат в новом потоке, взятом из
пула потоков (ThreadPool).
C#
Создаем новое C# консольное приложение... и напишем код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
// show message
Console.WriteLine("method Main started");
// запускаем задачу (выполняется в отдельном потоке)
Task<double> t = Task.Run(() =>
{
// show message
Console.WriteLine("Task started");
// выполняем длительный по времени рачсет (у меня занимает 20 секунд)
double sum = 1;
for (long i = 1; i < 298765431; i++)
sum += Math.Sqrt(i);
// show message
Console.WriteLine("Task end");
// return
return sum;
});
// show message
Console.WriteLine("Выводим результат на экран");
// ждем когда завершится поток с таском
double calculatedSum = t.Result;
// show message
Console.WriteLine("method Main end, result={0}", calculatedSum);
}
}
}
C#
// ждем когда завершится поток с таском
double calculatedSum = t.Result;