Upload
igor-shkulipa
View
63
Download
1
Embed Size (px)
Citation preview
Темы лекции: Асинхронное программирование в C#.
Практическое задание: Асинхронное программирование в C#.
Тренер: Игорь Шкулипа, к.т.н.
Платформа .Net и язык программирования C#.
Занятие 16
http://www.slideshare.net/IgorShkulipa 2
Асинхронное программирование
Асинхронное программирование — это набор методик дляреализации дорогостоящих операций, которые выполняютсяпараллельно с остальной частью программы. Одна из областей, гдечасто применяется асинхронное программирование, — программы сграфическим UI: как правило, замораживать UI до завершениядорогостоящей операции неприемлемо. Кроме того, асинхронныеоперации важны для серверных приложений, которым нужнопараллельно обрабатывать множество клиентских запросов.
К типичным примерам асинхронных операций, часто наблюдаемым напрактике, относятся отправка запроса на сервер и ожидание ответа,чтение данных с жесткого диска и выполнение ресурсоемкихвычислений вроде проверки правописания.
http://www.slideshare.net/IgorShkulipa 3
Библиотека параллельных задач
Библиотека параллельных задач (TPL), как и предполагает ее имя, основываетсяна концепции задачи. Термин параллелизм задач означает одновременноевыполнение одной или нескольких разных задач. Задача представляет собойасинхронную операцию и в некотором роде напоминает создание нового потокаили рабочего элемента ThreadPool, но на более высоком уровне абстракции.
Задачи предоставляют два основных преимущества.
• Более эффективное и масштабируемое использование системных ресурсов.
В фоновом режиме задачи помещаются в очередь ThreadPool,усовершенствованный с помощью алгоритмов, которые определяют инастраивают количество потоков, повышающих производительность. Этоделает задачи относительно простыми и позволяет создавать множество задачдля использования точного параллелизма. В дополнение к этому дляобеспечения балансировки нагрузки используются широко известныеалгоритмы переноса нагрузки.
• Больший программный контроль по сравнению с потоком или рабочимэлементом.
Задачи и построение платформы на их основе предоставляют богатый наборинтерфейсов API, которые поддерживают ожидание, отмену, продолжения,надежную обработку исключений, подробные состояния, пользовательскоепланирование и многое другое.
http://www.slideshare.net/IgorShkulipa 4
Тип Action<T>
public delegate void Action<in T>(T obj)
• T - тип параметра метода, инкапсулируемого данным делегатом.Этот параметр типа является контрвариантным. Это означает, чтоможно использовать либо указанный тип, либо менее производныйтип.
• obj - тип: T, Параметр метода, инкапсулируемого данным делегатом.
Делегат Action<T> можно использовать для передачи метода в качествепараметра без явного объявления пользовательского делегата.
Инкапсулируемый метод должен соответствовать заданной этимделегатом сигнатуре метода. Это означает, что инкапсулированный методдолжен иметь один параметр, передаваемый по значению, и не долженвозвращать значение.
http://www.slideshare.net/IgorShkulipa 5
Класс Task
using System.Threading.Tasks
[HostProtectionAttribute(SecurityAction.LinkDemand,
Synchronization = true,
ExternalThreading = true)]
public class Task : IAsyncResult, IDisposable
Представляет асинхронную операцию.
Task(Action) Инициализирует новую задачу Task с заданным действием.
Task(Action, CancellationToken)
Инициализирует новую задачу Task с заданными действием и токеном CancellationToken.
Task(Action, TaskCreationOptions)
Инициализирует новую задачу Task с заданными действием и параметрами создания.
Task(Action<Object>, Object)Инициализирует новую задачу Task с заданными действием и состоянием.
Task(Action, CancellationToken, TaskCreationOptions)
Инициализирует новую задачу Task с заданными действием и параметрами создания.
Task(Action<Object>, Object, CancellationToken)
Инициализирует новую задачу Task с заданными действием, состоянием и параметрами.
Task(Action<Object>, Object, TaskCreationOptions)
Инициализирует новую задачу Task с заданными действием, состоянием и параметрами.
Task(Action<Object>, Object, CancellationToken, TaskCreationOptions)
Инициализирует новую задачу Task с заданными действием, состоянием и параметрами.
http://www.slideshare.net/IgorShkulipa 6
Task. Свойства
AsyncStateВозвращает объект состояния, предоставленный при создании задачи Task, или значение NULL, если объект не предоставлен.
CreationOptionsВозвращает объект TaskCreationOptions, использованный при создании данной задачи.
CurrentIdВозвращает уникальный идентификатор выполняющейся в настоящее время задачи Task.
Exception
Возвращает объект AggregateException, который привел к преждевременному завершению задачи Task. Если Task завершенные успешно или пока не бросало исключений, это значение null.
FactoryПредоставляет доступ к методам фабрики для создания экземпляров Task и Task<TResult>.
IdВозвращает уникальный идентификатор данного экземпляра Task.
IsCanceledВозвращает значение, указывающее, завершилось ли выполнение данного экземпляра Task из-за отмены.
IsCompletedВозвращает значение, которое показывает, завершилась ли задача Task.
IsFaultedВозвращает значение, указывающее, завершилась ли задача Task из-за необработанного исключения.
Status Возвращает состояние TaskStatus данной задачи.
http://www.slideshare.net/IgorShkulipa 7
Task. Методы
http://msdn.microsoft.com/ru-ru/library/system.threading.tasks.task.aspx
http://www.slideshare.net/IgorShkulipa 8
Класс Parallel
Предоставляет поддержку параллельных циклов и областей.
[HostProtectionAttribute(SecurityAction.LinkDemand,
Synchronization = true,
ExternalThreading = true)]
public static class Parallel;
Методы:
• For + 10 перегрузок – выполняет цикл for с заданными аргументами• ForEach + 19 перегрузок – выполняет цикл foreach с заданными
аргументами• Invoke - выполняет все предоставленные действия, в том числе
параллельно.
http://www.slideshare.net/IgorShkulipa 9
Пример Task
Action<object> action = (object obj) =>
{
Console.WriteLine("Task={0}, Object={1}, Thread={2}",
Task.CurrentId, obj.ToString(),
Thread.CurrentThread.ManagedThreadId);
};
Task t1 = new Task(action, "StringObject1");
Task t2 = Task.Factory.StartNew(action, "StringObject2");
t2.Wait();
t1.Start();
t1.Wait();
Task t3 = new Task(action, "StringObject3");
t3.RunSynchronously();
t3.Wait();
Task=1, Object=StringObject2, Thread=11
Task=2, Object=StringObject1, Thread=11
Task=3, Object=StringObject3, Thread=10
http://www.slideshare.net/IgorShkulipa 10
Пример. Вычисление 10000 факториалов.Последовательная версия.
using System.Numerics;
class Program
{
static void Main(string[] args)
{
BigInteger FactorialsCount = 2000;
var Results = new Dictionary<BigInteger, BigInteger>();
Func<BigInteger, BigInteger> factorial = null;
factorial = (n) => (n == 0) ? 1 : n * factorial(n - 1);
for (BigInteger i = 0; i < FactorialsCount; i++)
{
Results.Add(i, factorial(i));
}
foreach (var item in Results)
{
Console.WriteLine("N={0}, Factorial={1}",
item.Key, item.Value);
}
Console.ReadKey();
}
}
http://www.slideshare.net/IgorShkulipa 11
Пример. Вычисление 10000 факториалов.Parallel версия.
using System.Numerics;
using System.Collections.Concurrent;
class Program
{
static void Main(string[] args)
{
int FactorialsCount = 10000;
var Results =
new ConcurrentDictionary<BigInteger, BigInteger>(4, FactorialsCount);
Func<int, BigInteger> factorial = null;
factorial = (n) =>
(n == 0) ? 1 : n * factorial(n - 1);
Parallel.For(0, FactorialsCount,
(i) =>
{
Results[i] = factorial(i);
});
foreach (var item in Results)
{
Console.WriteLine("N={0}, Factorial={1}",
item.Key, item.Value);
}
Console.ReadKey();
}
}
http://www.slideshare.net/IgorShkulipa 12
Пример. Вычисление 10000 факториалов.4-Parallel версия.
using System.Numerics;
using System.Collections.Concurrent;
class Program
{
static void Main(string[] args)
{
int FactorialsCount = 10000;
var Results =
new ConcurrentDictionary<BigInteger, BigInteger>(4, FactorialsCount);
Func<int, BigInteger> factorial = null;
factorial = (n) =>
(n == 0) ? 1 : n * factorial(n - 1);
for (int j = 0; j < 4; j++)
{
Parallel.For(j * 2500, (j + 1) * 2500,
(i) =>
{
Results[i] = factorial(i);
});
}
foreach (var item in Results)
{
Console.WriteLine("N={0}, Factorial={1}",
item.Key, item.Value);
}
Console.ReadKey();
}
}
http://www.slideshare.net/IgorShkulipa 13
Ключевое слово async
Модификатор async указывает, что модифицируемые им метод, лямбда-выражение, или анонимный метод являются асинхронными.
Асинронный метод может возвращать значение следующих типов: Task,Task<TResult> или void. Асинхронный метод не может принимать вкачестве своих аргументов параметры с модификаторами ref или out,но, при этом, он может вызывать методы, имеющие такие параметры.
Указывайте Task<TResult> в качестве типа значения, возвращаемогоасинхронным методом, в том случае, если оператор return этогометода возвращает операнд типа TResult. Если же асинхронный методпри своём завершении не возвращает имеющего смысл значения,используйте тип Task.
http://www.slideshare.net/IgorShkulipa 14
Оператор await
Оператор await применяется к задаче в асинхронных методах, для того,чтобы приостановить выполнение метода до тех пор, пока задача незавершится. Задача представляет собой выполняющихся работы.
Асинхронный метод, в котором используется await должен быть помеченмодификатором async. Такой метод, определенный с помощьюмодификатора async, и обычно содержащий один или нескольковыражений await, называется асинхронным методом.
http://www.slideshare.net/IgorShkulipa 15
Пример async и await
public class AsyncClassExample
{
public async Task<string> AsyncExample()
{
await Task.Delay(5000);
return "Async Method Finished";
}
}
class Program
{
static void Main(string[] args)
{
AsyncClassExample ace = new AsyncClassExample();
Task<string> t1 = ace.AsyncExample();
string result = t1.Result;
Console.WriteLine(result);
Console.ReadKey();
}
}Async Method Finished
http://www.slideshare.net/IgorShkulipa 16
Пример. Вычисление факториала 1000
public class AsyncFactorialClass {
public async Task<BigInteger> Factorial(BigInteger n) {
BigInteger result=0;
if (n == 0) return 1;
else
{
Task<BigInteger> t = Factorial(n - 1);
await t;
result = t.Result*n;
}
return result;
}
}
class Program {
static void Main(string[] args) {
AsyncFactorialClass ace = new AsyncFactorialClass();
Task<BigInteger> t1 = ace.Factorial(1000);
BigInteger result = t1.Result;
Console.WriteLine(result);
Console.ReadKey();
}
}
http://www.slideshare.net/IgorShkulipa 17
Факториал 1000
402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
http://www.slideshare.net/IgorShkulipa 18
Лабораторная работа №16. Асинхронное программирование в C#
В индивидуальных курсовых проектах при необходимости использоватьасинхронное программирование с помощью классов Task или Parallel, атак же асинхронные методы с модификатором async и операторомawait.