SlideShare una empresa de Scribd logo
Irán Reyes Fleitas
Temas: 
• TPL 
• Paralelización de código imperativo. 
• Programación Paralela con tareas(Task). 
• Colecciones de Concurrencia y Pipelines. 
• Estructuras para la coordinación de los datos. 
• Async
Evolución C#
• Paralelización de código imperativo 
•Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . 
• Programación Paralela con tareas(Task) 
•Task, TimeOuts, Cancelando, Excepciones, Retornando valores. 
• Colecciones de Concurrencia y Pipelines 
•ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, 
ConcurrentDictionary.
Parallel Class 
( System.Threading.Tasks ) 
Parallel.For 
Parallel.ForEach 
Parallel.Invoke
Parallel.Invoke 
La manera más simple de paralelizar varios métodos. 
Sintaxis: 
Invoke( Action [] ) 
Invoke( ParallelOptions, Action [] ) 
No se tiene garantía de orden. 
No retorna hasta que cada 
invocación no hay finalizado. 
GoToRiver GoToPark GoToZoo GoToPlainArea 
Parallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea); 
Parallel.Invoke( 
() => Walk.GoToPark("Santiago"), 
Walk.GoToRiver, 
delegate() { Walk.GoToZoo("26st"); }, 
Walk.GoToPlainArea); 
Patrón 
Fork/Join
3 posibles escenarios de paralelismo Escenario 
Ideal 
Ejemplo hipotético con una arquitectura con 
4 núcleos lógicos. 
1era ejecución 
GoToZoo 
GoToRiver 
GoToPark 
GoToPlainArea 
2da ejecución 
GoToPark 
GoToRiver 
GoToPlainArea 
GoToZoo 
3era ejecución 
GoToZoo 
GoToPlainArea 
GoToRiver 
GoToPark
Ventajas y Desventajas 
1. Es un método muy simple de lograr paralelismo sin tareas, ni hilos. 
1. Métodos con notables diferencias en cuanto al tiempo de ejecución. 
2. Cada llamada crea una sobrecarga antes de correr los métodos. 
3. Como todo código en paralelo, esta expuesto a existencias de 
interdependencia e incontrolables interacciones. 
4. No tiene garantía de orden.
Análisis de tiempo con respecto al secuencial 
Walk.GoToPark(); 
Walk.GoToRiver(); 
Walk.GoToZoo(); 
Walk.GoToPlainArea(); 
Ejemplo hipotético (figuras)con una 
arquitectura con 4 núcleos lógicos y 
mediciones con 2 núcleos lógicos 
Parallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea);
Parallel.For 
Versión paralelizada del clásico for. 
Sintaxis: 
For( Int32, Int32, Action<Int32> ) 
For( Int32, Int32, Action<Int32, ParallelLoopState> ) 
List<string> data = new List<string>(){"Estamos","paralelizando","el","for","y","el","foreach"}; 
Tradicional Paralelizado 
for (int i = 0; i < data.Count; i++) 
{ 
Console.Write(i); 
} 
Parallel.For(0, data.Count, x => 
{ 
Console.Write(x); 
}); 
No tiene por que cumplirse el orden. 
Tener en cuenta si los elementos 
estan relacionados entre si. 
Desde LowerBound a UpperBound. 
El primer parámetro es inclusivo, 
el segundo exclusivo. 
Load- 
Balance 
Pequeños bodies.
Análisis de tiempo con respecto al secuencial(RayTracing) 
void Render(Scene scene, Color[,] rgb) 
{ 
for (int y = 0; y < screenHeight; y++) 
{ 
for (int x = 0; x < screenWidth; x++) 
rgb[x,y] = TraceRay(new Ray(scene,x,y)); 
} 
} 
void Render(Scene scene, Color[,] rgb) 
{ 
Parallel.For(0, screenHeight, delegate(int y) 
{ 
for (int x = 0; x < screenWidth; x++) 
rgb[x,y] = TraceRay(new Ray(scene,x,y)); 
}); 
} 
Ocho núcleos y 350 x 350 
Secuencial: 1.7 fps 
Paralelo : 12 fps 
Dos núcleos y 350 x 350 
Secuencial: 1.0 fps 
Paralelo : 2.0 fps 
Dos núcleos y 578 x 485 
Secuencial: 0.5 fps 
Paralelo : 1.0 fps
Análisis de tiempo con respecto al secuencial(Primos) 
List<int> primes = new List<int>(); 
int cotaSup = 50000; 
for (int i = 2; i < cotaSup; i++) 
{ 
if (isPrime(i)) 
primes.Add(i); 
} 
Parallel.For(2, cotaSup, (i) => 
{ 
if (isPrime(i)) 
primes.Add(i); 
}); 
0.5 segundos 
0.2 segundos 
0.5/0.2 = 2.5x 
Ejemplo hipotético (figuras)con una 
arquitectura con 4 núcleos lógicos y 
mediciones con 2 núcleos lógicos
F# 
let sentences = [|"Estamos"; "paralelizando"; "el"; "for"; "y"; "el"; 
"foreach"|] 
for index=0 to sentences.Length do 
printfn "%d" index 
printfn "" 
let accion indice = 
printfn "%d" indice 
Parallel.For(0,sentences.Length, new Action<int>(accion)) 
Console.ReadKey();
Parallel.ForEach 
Versión paralelizada del clásico foreach. 
Sintaxis: 
ForEach <TSource>( IEnumerable <TSource>, Action <TSource> ) 
ForEach <TSource>( IEnumerable <TSource>, Action <TSource, ParallelLoopState> ) 
List<string> data = new List<string>(){"Estamos","paralelizando","el","for","y","el","foreach"}; 
foreach (var items in data) 
{ 
Console.Write(items + " "); 
} 
Tradicional Paralelizado 
Parallel.ForEach(data, x => 
{ 
Console.Write(x + " "); 
});
Análisis de tiempo con respecto al secuencial 
Ejemplo hipotético (figuras)con una 
arquitectura con 4 núcleos lógicos y 
mediciones con 2 núcleos lógicos 
foreach (var i in inputData) 
{ 
if (isPrime(i)) 
resultData[indice] = i; 
indice++; 
} 
28 segundos 
14 segundos 
var op = Partitioner.Create(inputData); 
Parallel.ForEach(op, (item, loopState, index) => 
{ 
28/14 = 2x 
if (isPrime(item)) 
resultData[index] = item; 
});
¿Como paramos los ciclos?(Cancelando) 
ParallelLoopState ParallelLoopResult 
ParallelLoopResult loopResult1 = Parallel.For(0, 10, (x, state) => 
{ 
if (x < 5) 
Console.WriteLine(x); 
else 
state.Stop(); 
}); 
ParallelLoopResult loopResult2 = Parallel.ForEach(data, (x, state) => 
{ 
if (!x.Equals("y")) 
Console.WriteLine(x); 
else 
state.Break(); 
}); 
Console.WriteLine(loopResult1.LowestBreakIteration); 
Console.WriteLine(loopResult1.IsCompleted); 
Console.WriteLine(loopResult2.LowestBreakIteration); 
Console.WriteLine(loopResult2.IsCompleted);
Manejo de Excepciones 
AggregateException 
Formato: 
try 
{ 
..... 
..... 
} 
catch (AggregateException aggEx) 
{ 
foreach (Exception ex in aggEx.InnerExceptions) 
{ 
Console.WriteLine(string.Format("Caught exception '{0}'",ex.Message)); 
} 
}
Manejo de Excepciones 
Ejemplo: 
try 
{ 
ParallelLoopResult loopResult = Parallel.For(0, 10, (x, state) => 
{ 
if (x < 5) 
Console.WriteLine(x); 
else 
{ 
var ex = "Excepción en el índice " + x; 
throw new InvalidDataException(ex); 
} 
}); 
Console.WriteLine("Ciclo for completado: {0}", loopResult.IsCompleted); 
} 
catch (AggregateException aggEx) 
{ 
foreach (var innerException in aggEx.InnerExceptions) 
{ 
//Pueden haber 2 excepciones a causa del paralelismo. 
Console.WriteLine("Excepcion capturada: " + innerException.Message); 
} 
}
ParallelOptions 
ParallelOptions.MaxDegreeOfParallelism 
ParallelOptions.TaskScheduler 
ParallelOptions.CancellationToken 
Se utilizan en los 
métodos de Parallel. 
var source = Enumerable.Range(8, 2000).ToArray(); 
double[] result = new double[source.Length]; 
ParallelOptions parallelOptions = new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount*2; //Ejemplo 
Parallel.ForEach(Partitioner.Create(8, source.Length),parallelOptions, range => 
{ 
for (int i = range.Item1; i < range.Item2; i++) 
result[i] = source[i]*Math.E; 
});
Particionando 
Partición por rangos Partición por bloques 
Partitioner.Create(1,40) 
Parallel.ForEach(Partitioner.Create(10, 200), range => 
{ 
Console.WriteLine("{0},{1}",range.Item1,range.Item2); 
for (int i = range.Item1; i < range.Item2; i++) 
{ 
data[i] = data[i]*i; 
} 
}); 
Optimizando el particionado según el número de núcleos. 
Partitioner.Create(1,40, ((numeroDeElementos 
/numeroDeNucleos)+1)) 
System.Environment.ProcessorCount 
Sintaxis: 
Create <TSource >( IEnumerable<TSource > ) 
Create ( Int32, Int32) 
Create ( Int32, Int32, Int32)
• Paralelización de código imperativo 
•Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . 
• Programación Paralela con tareas(Task) 
•Task, TimeOuts, Cancelando, Excepciones, Retornando valores. 
• Parallel Linq (PLinq) 
•Operadores, Cancelando, Agregaciones, Excepciones. 
• Colecciones de Concurrencia y Pipelines 
•ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, 
ConcurrentDictionary.
Task
Task - Scheduling
Ciclo de vida y estado de una tarea 
EnumTaskStatus 
Miembros: 
Created 
WaitingForActivation 
WaitingToRun 
Running 
WaitingForChildrenToComplete 
RanToCompletion 
Canceled 
Faulted
Invocando Tareas 
GenerateSomething GenerateNothing 
Parallel.Invoke(GenerateSomething,() => GenerateNothing()); 
//Los métodos no están corriendo todavía, pero las tareas 
están listas para empezar. 
//El estado para ambas tareas es TaskStatus.Created. 
var task1 = new Task(GenerateSomething); 
var task2 = new Task(() => GenerateNothing()); 
task1.Start(); 
task2.Start(); 
Task.WaitAll(task1, task2); 
var task1 = Task.Factory.StartNew(() => GenerateNothing());
TimeOuts 
var task1 = new Task(GenerateSomethingTimeOut); 
var task2 = new Task(() => GenerateNothing()); 
task1.Start(); 
task2.Start(); 
if(!Task.WaitAll(new Task[]{task1,task2},300)) 
{ 
Console.WriteLine("GenerateSomething y GenerateNothing han tardado más de 
300ms"); 
} 
if(!task1.Wait(300)) 
{ 
Console.WriteLine("GenerateSomething ha tardado más de 300ms"); 
}
Manejando excepciones con las Task 
static void GenerateSomethingCancel(CancellationToken cancellationToken) 
{ 
cancellationToken.ThrowIfCancellationRequested(); 
Console.WriteLine("GenerateSomething"); 
Thread.Sleep(3000); 
if (sw.Elapsed.Seconds > 1) 
throw new TimeoutException("La tarea se demoró mas de 1 segundos"); 
cancellationToken.ThrowIfCancellationRequested(); 
} 
try 
{ 
// Espera por que todas las tareas finalicen en menos de 3 segundos 
if (!Task.WaitAll(new Task[] { task1, task2 }, 3000)) 
{ 
Console.WriteLine("GenerateSomething y GenerateNothing han tardado más de 300ms en terminar"); 
Console.WriteLine(task1.Status.ToString()); 
Console.WriteLine(task2.Status.ToString()); 
} 
} 
catch (AggregateException ex) 
{ 
foreach (Exception innerEx in ex.InnerExceptions) 
{ 
Console.WriteLine(innerEx.ToString()); 
} 
}
Retornando valores desde las tareas 
static List<string> GenerateSomethingReturn() 
{ 
Console.WriteLine("GenerateSomething"); 
Thread.Sleep(3000); 
return new List<string>{"Estoy","retornando","una","lista","de","strings."}; 
} 
var task1 = Task.Factory.StartNew(() => GenerateSomethingReturn()); 
try 
{ 
task1.Wait(); 
} 
catch (AggregateException ex) 
{ 
foreach (Exception innerEx in ex.InnerExceptions) 
{ 
Console.WriteLine(innerEx.ToString()); 
} 
} 
var task2 = Task.Factory.StartNew(() => 
{ 
foreach (var result in task1.Result) 
{ 
Console.WriteLine(result); 
} 
});
Cancelando Tareas usando Tokens 
CancellationToken cancellationToken 
CancellationTokenSource 
Se pasa como parámetro 
Controla la cancelación desde el método principal 
static void GenerateSomethingCancel(CancellationToken cancellationToken) 
{ 
cancellationToken.ThrowIfCancellationRequested(); 
Console.WriteLine("GenerateSomething"); 
Thread.Sleep(3000); 
cancellationToken.ThrowIfCancellationRequested(); 
} 
var cts = new CancellationTokenSource(); 
var ct = cts.Token; 
var task1 = Task.Factory.StartNew(() => GenerateNothingCancel(ct),ct); 
cts.Cancel(); 
if (task1.IsCanceled) 
{ 
Console.WriteLine("La Tarea GenerateSomethingCancel que estaba en ejecucion fue cancelada"); 
}
TaskCreationOptions 
Optimizando el código 
TaskCreationOptions.AttachedToParent 
TaskCreationOptions.None 
TaskCreationOptions.LongRunning 
TaskCreationOptions.PreferFairness 
var task2 = Task.Factory.StartNew(() => 
Ayudar al Scheduler 
{ 
foreach (var result in task1.Result) 
{ 
Console.WriteLine(result); 
} 
},TaskCreationOptions.PreferFairness);
Concatenando múltiples tareas usando Continuación 
try 
{ 
var task1 = Task.Factory.StartNew(() => GenerateSomethingCancelReturn(ct), ct); 
var task2 = task1.ContinueWith(t => 
{ 
foreach (var result in t.Result) 
{ 
Console.WriteLine(result); 
} 
}); 
task1.Wait(); 
} 
catch (AggregateException ex) 
{ 
foreach (Exception innerEx in ex.InnerExceptions) 
{ 
Console.WriteLine(innerEx.ToString()); 
} 
} 
var task2 = Task.Factory.StartNew(() => 
{ 
foreach (var result in task1.Result) 
{ 
Console.WriteLine(result); 
} 
});
var f = Task.Factory; 
var build1 = f.StartNew(() => Build(project1)); 
var build2 = f.StartNew(() => Build(project2)); 
var build3 = f.StartNew(() => Build(project3)); 
var build4 = build1.ContinueWith(() => Build(project4)); 
var build5 = f.ContinueWhenAll(new[] { build1, build2, build3 }, () => Build(project5)); 
var build6 = f.ContinueWhenAll(new[] { build3, build4 }, () => Build(project6)); 
var build7 = f.ContinueWhenAll(new[] { build5, build6 }, () => Build(project7)); 
var build8 = build5.ContinueWith(() => Build(project8)); 
Task.WaitAll(build1, build2, build3, build4, build5, build6, build7, build8);
Mezclando paralelismo y código secuencial con Continuación
TaskContinuationOptions 
TaskContinuationOptions.AttachedToParent 
TaskContinuationOptions.ExecuteSynchronously 
TaskContinuationOptions.LongRunning 
TaskContinuationOptions.PreferFairness 
TaskContinuationOptions.None 
TaskContinuationOptions.NotOnCanceled 
TaskContinuationOptions.NotOnFaulted 
TaskContinuationOptions.NotOnRanToCompletion 
TaskContinuationOptions.OnlyOnCanceled 
TaskContinuationOptions.OnlyOnFaulted 
TaskContinuationOptions.OnlyOnRanToCompletion 
var task2 = task1.ContinueWith(t => 
{ 
foreach (var result in t.Result) 
{ 
Console.WriteLine(result); 
} 
},TaskContinuationOptions.None); 
Especificando el comportamiento 
de la próxima tarea 
Condicionando la próxima tarea
Análisis de tiempo con respecto a los Thread 
Ejemplo hipotético con una arquitectura 
con 2 núcleos lógicos. 
64 Threads versus 64 Tasks 
1. Los primos hasta el 50 : Thread 0.9 segundos. 
Tasks 0.2 segundos. 
2. Los primos hasta el 500 : Thread 2 segundos. 
Tasks 1 segundo. 
3. Los primos hasta el 5000 : Thread 15 segundos. 
Tasks 13 segundos. 
4. Los primos hasta el 50000: Thread 116 segundos. 
Tasks 104 segundos.
• Paralelización de código imperativo 
•Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . 
• Programación Paralela con tareas(Task) 
•Task, TimeOuts, Cancelando, Excepciones, Retornando valores. 
• Colecciones de Concurrencia y Pipelines 
•ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, 
ConcurrentDictionary.
var data = new List<int>(); 
Parallel.ForEach(Partitioner.Create(0, 200), range => 
{ 
for (int i = range.Item1; i < range.Item2; i++) 
lock (data) 
data.Add(i); 
}); 
data.ForEach(x => Console.Write(x + " ")); 
Solución
Colecciones Thread-Unsafe: 
System.Collections 
System.Collections.Generic 
Colecciones Thread-Safe: 
System.collections.Concurrent 
ConcurrentQueue<T> 
ConcurrentStack<T> 
ConcurrentBag<T> 
ConcurrentDictionary<TKey, TValue> 
BlockingCollection<T> 
IProducerConsumerCollection<T>
Colecciones de concurrencia ideales para 
escenarios productor-consumidor.
ConcurrentQueue<T> 
Lock-Free 
Métodos Importantes: 
Enqueue 
TryDequeue 
TryPeek
ConcurrentQueue<T> 
-Esta coleccion es completamente libre de lock (lock-free) 
-Usa compare and swap (CAS) 
-Cuando falla una operacion CAS se pone en estado de 
contencion.
ConcurrentQueue<T> 
-Produce (over-head). 
-Mejora el rendimiento de la cola y otras colecciones 
thread-unsafe, en determinados escenarios. 
-Nos facilita el trabajo con la concurrencia.
ConcurrentQueue<T> 
Caracteristicas importantes: 
concurrentQueue.Enqueue(item); 
if (concurrentQueue.TryPeek(out item)) 
{ 
DoSomething(item); 
} 
if (concurrentQueue.TryDequeue(out item)) 
{ 
DoSomething(item); 
}
ConcurrentStack<T> 
Métodos Importantes: 
Push 
TryPop 
TryPeek
ConcurrentStack<T> 
Otros Métodos: 
PushRange 
PopRange
ConcurrentStack<T> 
-Similar a la coleccion ConcurrentQueue. 
-Es una coleccion LIFO. 
-Atomicidad en los metodos PushRange y PopRange reduce la cantidad 
de insersiones y extracciones concurrentes en la coleccion.
ConcurrentStack<T> 
Caracteristicas importantes: 
concurrentStack.Push(item); 
if (concurrentStack.TryPeek(out item)) 
{ 
DoSomething(item); 
} 
if (concurrentStack.TryPop(out item)) 
{ 
DoSomething(item); 
}
ConcurrentStack<T> 
Caracteristicas importantes: 
Parallel.ForEach(Partitioner.Create(0, partCount), p => 
{ 
concurrentStack.PushRange 
( 
numberArray, p.Item1, p.Item2 - p.Item1 
); 
});
ConcurrentStack<T> 
Sintaxis: 
count = s.TryPopRange(numberArray, 0, numberArray.Length); 
count = s.TryPopRange(numberArray); 
Count sera la cantidad de objetos que fueron sacados del tope de 
la cola e insertados el el array.
TPL - Colecciones de Concurrencia y Pipelines 
Atomiciadad o costo… 
PushRange 
TryPopRange 
Push 
TryPop 
Buen rendimiento 
Igual concurrencia 
No Over-Head 
No memoria 
adicional 
Over-Head 
Memoria adicional 
Atomiciadad 
Menor 
concurrencia
ConcurrentBag<T> 
Métodos Importantes: 
Add 
TryTake 
TryPeek 
Nota: 
Colección donde el orden no importa. 
Ideal para escenarios Productor – Consumidor.
ConcurrentBag<T> 
-Ideal para ciertos escenarios productor-consumidor. 
-No es completamente lock-free. 
-Bastante ineficiente, donde el hilo productor es distinto al consumidor. 
-Mantiene una cola local para cada hilo que accede a ella.
ConcurrentBag<T> 
Caracteristicas importantes: 
sentencesBag.Add(s.ToString()); 
string sentence; 
if (_sentencesBag.TryTake(out sentence)) 
{ 
_capWordsInSentencesBag.Add 
( 
CapitalizeWords(delimiterChars, sentence, '' 
)); 
}
BlockingCollection<T> 
Métodos Importantes: 
Add 
TryAdd 
Take 
TryTake 
CompleteAdding 
GetConsumerEnumerable 
Ofrece soporte para Bounding y Blocking. 
Ideal para escenarios Productor – Consumidor. 
Ideal para implementaciones de pipelines. 
Capacidad máxima opcional. 
Permite cancelación a través de tokens. 
Es un wrapper para una interfaz del tipo IProducerConsumerCollection<T> 
Existen 2 tipos de enumeraciones con foreach: 
1. Enumeración de solo lectura. 
2. Enumeración que elimina los elementos que han sido enumerados(P-C).
BlockingCollection<T> 
Caracteristicas importantes: 
BlockingCollection<int> stackBC = new BlockingCollection<int> 
(new ConcurrentStack<int>()); 
BlockingCollection<int> bagBC = new BlockingCollection<int> 
(new ConcurrentBag<int>()); 
BlockingCollection<int> bc = new BlockingCollection<int>(count);
BlockingCollection<T> 
Caracteristicas importantes: 
IsCompleted, IsAddingCompleted. 
string aux; 
while (!sentences.IsCompleted) 
{ 
if (sentences.TryTake(out aux)) 
upperSentences.Add(aux.ToUpper()); 
} 
upperSentences.CompleteAdding();
BlockingCollection<T> 
Caracteristicas importantes: 
GetConsumingEnumerable() 
foreach (var item in upperSentences.GetConsumingEnumerable()) 
{ 
finalSentences.Add(item.Replace("U", "")); 
} 
upperSentences.CompleteAdding();
BlockingCollection<T> 
Caracteristicas importantes: 
if (!_sentencesBC.TryAdd(newSentence, 2000, cancToken)) 
{ 
throw new TimeoutException( 
"_sentencesBC took more than 2 seconds to add an item"); 
} 
catch (OperationCanceledException ex) 
{ 
// The operation was cancelled 
break; 
}
BlockingCollection<T> 
Caracteristicas importantes: 
BlockingCollection<TOutput>.AddToAny(Output, result, _token); 
BlockingCollection<TOutput>.TryAddToAny(Output, result, 
timeOut, _token);
BlockingCollection<T> 
Caracteristicas importantes: 
BlockingCollection<TOutput>.AddToAny(array, item, _token); 
BlockingCollection<TOutput>.TryAddToAny(array, item, 
timeOut, _token); 
Estos metodos devuelven el indice de la coleccion, en el array de 
colecciones, a la cual se le agrego el elemento.
BlockingCollection<T> 
Caracteristicas importantes: 
BlockingCollection<TOutput>.TakeFromAny(array, out item, _token); 
BlockingCollection<TOutput>.TakeFromAny(array, out item, 
timeOut, _token); 
Estos metodos devuelven el indice de la coleccion, en el array de 
colecciones, de la cual se elimino el elemento.
BlockingCollection<T> 
-Facilita el trabajo con las colecciones thread-safe. 
-Produce Over-Head. 
-Disminuye la cantidad y simplfica la complejidad del codigo. 
-Ideal para la implementacion de pipelines(Ejemplo)
ConcurrentDictionary<T> 
Lock-Free para 
operaciones de 
lectura 
Métodos Importantes: 
AddOrUpdate 
GetEnumerator 
GetOrAdd 
TryAdd 
TryGetValue 
TryRemove 
TryUpdate 
Sintaxis: 
ConcurrentDictionary<TKey, TValue >() 
ConcurrentDictionary<TKey, TValue >(Int32, Int32) 
int initialCapacity = 100; 
int concurrencyLevel = Environment.ProcessorCount * 2; 
ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, 
int>(concurrencyLevel, initialCapacity); 
for (int i = 0; i < 64; i++) 
cd[i] = i * i; 
Console.WriteLine(“23² is {0} (should be {1})", cd[23], 23 * 23);
ConcurrentDictionary<Tkey, TValue> 
Caracteristicas importantes: 
_rectanglesDict.AddOrUpdate( 
newKey, newRect, 
(key, existingRect) => 
{if (existingRect != newRect) 
{ 
lock (existingRect) 
{ 
existingRect.Update( 
newRect.Location, newRect.Size); 
} 
return existingRect; 
} 
else { 
return existingRect; 
} 
});
Asynchronous 
Programming 
Model(APM) 
Event-based 
Asynchronous 
Pattern(EAP) 
Task 
Asynchronous 
Pattern(TAP) 
Patrones estándares 
Idea 
Sincrónico = Asincrónico 
TAP 
APM 
EAP
Microsoft Visual Studio AsyncCommunity Technology Preview (CTP). 
( Visual Studio Async CTP ) 
Nuevas keywords: 
async: 
await: 
Marca a métodos o expresiones lambdas como asincrónicas. 
Retiene el control hasta que la operación asincrónica termine. 
Objetivo: 
Programación asincrónica = Programación sincrónica. 
Escribir códigos simples y fáciles de entender. 
Fin de los métodos callback.
public int SumPageSizes(IList<Uri> uris) 
{ 
int total = 0; 
foreach (var uri in uris) 
{ 
statusText.Text = string.Format("Found {0} bytes ...", total); 
var data = new WebClient().DownloadData(uri); 
total += data.Length; 
} 
statusText.Text = string.Format("Found {0} bytes total", total); 
return total; 
} 
Versión Sincrónica 
Problemas: 
Bloquea la interfaz de usuario. 
No nos va enseñando el estado de la descarga. 
Solución Versión Asincrónica
Versión Asíncrona con EAP 
public void SumPageSizesAsync(IList<Uri> uris) 
{ 
SumPageSizesAsyncHelper(uris.GetEnumerator(), 0); 
} 
private void SumPageSizesAsyncHelper(IEnumerator<Uri> enumerator, int total) 
{ 
if (enumerator.MoveNext()) 
{ 
statusText.Text = string.Format("Found {0} bytes ...", total); 
var client = new WebClient(); 
client.DownloadDataCompleted += (sender, e) => SumPageSizesAsyncHelper(enumerator, 
total + e.Result.Length); 
client.DownloadDataAsync(enumerator.Current); 
} 
else 
{ 
statusText.Text = string.Format("Found {0} bytes total", total); 
enumerator.Dispose(); 
} 
} 
Problemas: 
Hay que romper el foreach. 
En cada llamado se ancla un evento. 
El código es recursivo. 
No retorna el total una ves calculado.
Conclusiones 
El método anterior es asincrónico con una sola llamada asincrónica y una sola 
estructura de control alrededor de esta. Imagínense más llamadas asincrónicas 
y más estructuras de control, sería un verdadero caos. 
Primera solución: Utilizar APM o EAP con las nuevas clases de TPL. 
Segunda solución: Utilizar TAP(junto a async). 
public async Task<int> SumPageSizesAsyncBest(IList<Uri> uris) 
{ 
int total = 0; 
foreach (var uri in uris) 
{ 
statusText.Text = string.Format("Found {0} bytes ...", total); 
var data = await new WebClient().DownloadDataTaskAsync(uri); 
total += data.Length; 
} 
statusText.Text = string.Format("Found {0} bytes total", total); 
listBox1.Items.Add(total.ToString()); 
return total; 
}
let asyncProcessFile (filePath : string) = 
async { 
printfn "Procesando fichero [%s]" (Path.GetFileName(filePath)) 
use fileStream = new FileStream(filePath,FileMode.Open) 
let bytesToRead = int fileStream.Length 
let! data = fileStream.AsyncRead(bytesToRead) //Returna un objeto Async<byte[]> 
printfn “Se leyeron [%d] bytes" data.Length 
use resultFile = new FileStream(filePath + ".results", FileMode.Create) 
do! resultFile.AsyncWrite(data,0,data.Length) 
printfn "Finalizado el procesamiento del archivo [%s]" <| Path.GetFileName(filePath) 
} |> Async.Start 
asyncProcessFile "./testAsync.txt" 
Console.ReadKey(); 
async en F#
Retorno 
public async void SumPageSizesAsyncBestOther(IList<Uri> uris){ 
int total = 0; 
foreach (var uri in uris) 
{ 
statusText.Text = string.Format("Found {0} bytes ...", total); 
var data = await new WebClient().DownloadDataTaskAsync(uri); 
total += data.Length; 
} 
statusText.Text = string.Format("Found {0} bytes total", total); 
listBox1.Items.Add(total.ToString()); 
} 
( Fire and forget ) 
private async void sumButton_Click(object sender, RoutedEventArgs e) { 
sumButton.IsEnabled = false; 
await SumPageSizesAsync(GetUrls())); 
sumButton.IsEnabled = true; 
} 
( Incluyendo genéricas)
Código final propuesto 
public async Task<int> SumPageSizesAsyncBetter(IList<Uri> uris) 
{ 
var tasks = from uri in uris select new WebClient().DownloadDataTaskAsync(uri); 
var data = await TaskEx.WhenAll(tasks); 
return await TaskEx.Run(() =>data.Sum(s => s.Length)); 
} 
Nota: 
Se propone incluir Run() y WhenAll() en la claseTask cuando async arrive a su 
versión final; mientras este en CTP se alojarán en una clase de prueba llamada 
TaskEx.
¿Como funciona async? 
Original Transformado por el compilador 
public static async Task DoSum(int from,int to) 
{ 
int result = await Sum(from, to); 
string param = result.ToString() + "rn"; 
File.AppendAllText(@"./result.txt", param); 
} 
public static Task<int> Sum(int from, int to) 
{ 
Task<int> sum = TaskEx.Run(() => 
{ 
int result = 0; 
for (int i = from; i <= to; i++) 
{ 
TaskEx.Delay(500); 
result += i; 
} 
return result; 
}); 
return sum; 
} 
public static Task DoSum(int from,int to) 
{ 
var task1 = Task.Factory.StartNew(() => Sum(from,to)); 
return task1.ContinueWith((antecedentTask) => 
{ 
string param = antecedentTask.Result.Result.ToString() + rn"; 
File.AppendAllText(@"./result.txt", param); 
}); 
} 
public static Task<int> Sum(int from, int to) 
{ 
Task<int> sum = TaskEx.Run(() => 
{ 
int result = 0; 
for (int i = from; i <= to; i++) 
{ 
TaskEx.Delay(500); 
result += i; 
} 
return result; 
}); 
return sum; 
}
Como funciona async 
static void Main(string[] args) 
{ 
public static async Task DoSum(int from,int to) 
{ 
int result = await Sum(from, to); 
string param = result.ToString() + "rn"; 
File.AppendAllText(@"./result.txt", param); 
} 
int number; 
string input; 
Task myTask = new Task(Console.WriteLine); 
while (true) 
{ 
Console.WriteLine("Entre un número: "); 
input = Console.ReadLine(); 
if (string.Empty == input) 
break; 
number = int.Parse(input); 
myTask = DoSum(1, number); 
} 
myTask.Wait(); 
} 
Continua la ejecución. 
Retorna una tarea 
Callback En cuanto la tarea finalice.
public async Task<int> SumPageSizesAsyncBest(IList<Uri> uris) 
{ 
int total = 0; 
foreach (var uri in uris) 
{ 
statusText.Text = string.Format("Found {0} bytes ...", total); 
var data = await new WebClient().DownloadDataTaskAsync(uri); 
total += data.Length; 
} 
statusText.Text = string.Format("Found {0} bytes total", total); 
listBox1.Items.Add(total.ToString()); 
return total; 
} 
Retornando valores desde async
Cancelación desde async 
C# F# 
public async void Inicio(Program program) 
{ 
cts = new CancellationTokenSource(); 
program.Hola(cts.Token); 
Thread.Sleep(1000); 
if (cts != null) cts.Cancel(); 
} 
public async Task Hola(CancellationToken ct) 
{ 
Console.WriteLine("Before await"); 
await TaskEx.Delay(5000); 
ct.ThrowIfCancellationRequested(); 
Console.WriteLine("After await"); 
} 
let cancelableTask = 
async { 
printfn "Waiting 10 seconds..." 
for i = 1 to 10 do 
printfn "%d..." i 
do! Async.Sleep(1000) 
printfn "Finished!" 
} 
// Callback used when the operation is canceled 
let cancelHandler (ex : OperationCanceledException) 
= 
printfn "The task has been canceled." 
Async.TryCancelled(cancelableTask,cancelHandler) 
|>Async.Start 
Thread.Sleep(2000) 
Async.CancelDefaultToken()
Excepciones desde async 
try 
{ 
string txt = await w.DownloadStringTaskAsync(url); 
} 
catch(WebException x) 
{ 
--- Handle exception. 
} 
let asyncOperation = 
async { 
try 
// ... 
with 
| :? IOException as ioe -> 
printfn "IOException: %s" ioe.Message 
| :? ArgumentException as ae -> 
printfn "ArgumentException: %s" ae.Message 
} 
Las excepciones 
se manejan 
igual que de 
manera 
sincrónica.

Más contenido relacionado

La actualidad más candente

Unidad iii pilas y colas
Unidad iii pilas y colasUnidad iii pilas y colas
Unidad iii pilas y colas
TAtiizz Villalobos
 
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
Pablo Alvarez Doval
 
Java::Acceso a Bases de Datos
Java::Acceso a Bases de DatosJava::Acceso a Bases de Datos
Java::Acceso a Bases de Datos
jubacalo
 
Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1
Antares Zehcnas
 
Seminario 2
Seminario 2Seminario 2
Seminario 2
Sebastian Peralta
 
PEP-3156: Async I/O en Python
PEP-3156: Async I/O en PythonPEP-3156: Async I/O en Python
PEP-3156: Async I/O en Python
Saúl Ibarra Corretgé
 
Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en C
degarden
 
Transformaciones modelo a modelo: ATL (ParteII)
Transformaciones modelo a modelo: ATL (ParteII)Transformaciones modelo a modelo: ATL (ParteII)
Transformaciones modelo a modelo: ATL (ParteII)
Ricardo Tesoriero
 
Programa Java que gestiona los productos que comercializan varios viveros
Programa Java que gestiona los productos que comercializan varios viverosPrograma Java que gestiona los productos que comercializan varios viveros
Programa Java que gestiona los productos que comercializan varios viveros
jubacalo
 
Pyrapidc
PyrapidcPyrapidc
Pyrapidc
Matias Lang
 
Pila
PilaPila
Informe minishell
Informe minishellInforme minishell
Informe minishell
Alex Pin
 
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPCEjemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
Ivan Luis Jimenez
 
bibliotecas c++
bibliotecas c++bibliotecas c++
bibliotecas c++
Gustavo Castillo
 
S6-EDD-3.2 Pilas y colas
S6-EDD-3.2 Pilas y colasS6-EDD-3.2 Pilas y colas
S6-EDD-3.2 Pilas y colas
Luis Fernando Aguas Bucheli
 
Programacion en python_2
Programacion en python_2Programacion en python_2
Programacion en python_2
wozgeass
 
Node al limite con Nest
Node al limite con NestNode al limite con Nest
Node al limite con Nest
Arturo Silvelo
 
Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02
Henrry Eliseo Navarro Chinchilla
 
Charla Mysql
Charla MysqlCharla Mysql
Charla Mysql
Matías Alejo Garcia
 

La actualidad más candente (19)

Unidad iii pilas y colas
Unidad iii pilas y colasUnidad iii pilas y colas
Unidad iii pilas y colas
 
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
Depuración Avanzada Con Win Dbg Y Vs 2010 (Basica)
 
Java::Acceso a Bases de Datos
Java::Acceso a Bases de DatosJava::Acceso a Bases de Datos
Java::Acceso a Bases de Datos
 
Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1
 
Seminario 2
Seminario 2Seminario 2
Seminario 2
 
PEP-3156: Async I/O en Python
PEP-3156: Async I/O en PythonPEP-3156: Async I/O en Python
PEP-3156: Async I/O en Python
 
Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en C
 
Transformaciones modelo a modelo: ATL (ParteII)
Transformaciones modelo a modelo: ATL (ParteII)Transformaciones modelo a modelo: ATL (ParteII)
Transformaciones modelo a modelo: ATL (ParteII)
 
Programa Java que gestiona los productos que comercializan varios viveros
Programa Java que gestiona los productos que comercializan varios viverosPrograma Java que gestiona los productos que comercializan varios viveros
Programa Java que gestiona los productos que comercializan varios viveros
 
Pyrapidc
PyrapidcPyrapidc
Pyrapidc
 
Pila
PilaPila
Pila
 
Informe minishell
Informe minishellInforme minishell
Informe minishell
 
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPCEjemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
Ejemplo de RPC (Servidor de Archivos) enviar archivo en Java utilizando RPC
 
bibliotecas c++
bibliotecas c++bibliotecas c++
bibliotecas c++
 
S6-EDD-3.2 Pilas y colas
S6-EDD-3.2 Pilas y colasS6-EDD-3.2 Pilas y colas
S6-EDD-3.2 Pilas y colas
 
Programacion en python_2
Programacion en python_2Programacion en python_2
Programacion en python_2
 
Node al limite con Nest
Node al limite con NestNode al limite con Nest
Node al limite con Nest
 
Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02
 
Charla Mysql
Charla MysqlCharla Mysql
Charla Mysql
 

Similar a Getting deeper with TPL & async (Spanish version)

PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
Víctor Bolinches
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en Android
Droidcon Spain
 
Java 7- Java Day Guatemala
Java 7- Java Day GuatemalaJava 7- Java Day Guatemala
Java 7- Java Day Guatemala
Víctor Leonel Orozco López
 
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
TestingUy
 
Property Based Testing usando QuickCheck
Property Based Testing usando QuickCheckProperty Based Testing usando QuickCheck
Property Based Testing usando QuickCheck
guillecabeza
 
Sistemas operativos unidad 2
Sistemas operativos unidad 2Sistemas operativos unidad 2
Sistemas operativos unidad 2
Luis Cigarroa
 
Javascript
JavascriptJavascript
Javascript
Daniel Grippo
 
Apache spark meetup
Apache spark meetupApache spark meetup
Apache spark meetup
Israel Gaytan
 
Procesamiento de datos a gran escala con Apache Spark
Procesamiento de datos a gran escala con Apache SparkProcesamiento de datos a gran escala con Apache Spark
Procesamiento de datos a gran escala con Apache Spark
Software Guru
 
Java 8
Java 8Java 8
Java 8
BVision
 
Concurrencia en Java
Concurrencia en Java Concurrencia en Java
Concurrencia en Java
Pedro Gonzalez
 
5 c iterative
5 c iterative5 c iterative
5 c iterative
Yulisa Reyes Custodio
 
Ciclos Java - NetsBeans - Algoritmia
Ciclos Java - NetsBeans - AlgoritmiaCiclos Java - NetsBeans - Algoritmia
Ciclos Java - NetsBeans - Algoritmia
Daniel Gómez
 
Introducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronasIntroducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronas
albertoalcolea
 
News40 Parallel Computing
News40 Parallel ComputingNews40 Parallel Computing
News40 Parallel Computing
Lluis Franco
 
MODELO PASO DE MENSAJES
MODELO PASO DE MENSAJESMODELO PASO DE MENSAJES
MODELO PASO DE MENSAJES
Ing Eduardo Perez Hernandez
 
Python workshop
Python workshopPython workshop
TUTORIAL JAVA
TUTORIAL JAVATUTORIAL JAVA
TUTORIAL JAVA
denis ticona condori
 
Bases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCBases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBC
Carlos Hernando
 
JAVA.PPT
JAVA.PPTJAVA.PPT
JAVA.PPT
GalvanGR
 

Similar a Getting deeper with TPL & async (Spanish version) (20)

PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en Android
 
Java 7- Java Day Guatemala
Java 7- Java Day GuatemalaJava 7- Java Day Guatemala
Java 7- Java Day Guatemala
 
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
Charla evento TestingUY 2015 - Property-Based Testing Usando Quickcheck, o có...
 
Property Based Testing usando QuickCheck
Property Based Testing usando QuickCheckProperty Based Testing usando QuickCheck
Property Based Testing usando QuickCheck
 
Sistemas operativos unidad 2
Sistemas operativos unidad 2Sistemas operativos unidad 2
Sistemas operativos unidad 2
 
Javascript
JavascriptJavascript
Javascript
 
Apache spark meetup
Apache spark meetupApache spark meetup
Apache spark meetup
 
Procesamiento de datos a gran escala con Apache Spark
Procesamiento de datos a gran escala con Apache SparkProcesamiento de datos a gran escala con Apache Spark
Procesamiento de datos a gran escala con Apache Spark
 
Java 8
Java 8Java 8
Java 8
 
Concurrencia en Java
Concurrencia en Java Concurrencia en Java
Concurrencia en Java
 
5 c iterative
5 c iterative5 c iterative
5 c iterative
 
Ciclos Java - NetsBeans - Algoritmia
Ciclos Java - NetsBeans - AlgoritmiaCiclos Java - NetsBeans - Algoritmia
Ciclos Java - NetsBeans - Algoritmia
 
Introducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronasIntroducción a Celery y las colas de tareas asíncronas
Introducción a Celery y las colas de tareas asíncronas
 
News40 Parallel Computing
News40 Parallel ComputingNews40 Parallel Computing
News40 Parallel Computing
 
MODELO PASO DE MENSAJES
MODELO PASO DE MENSAJESMODELO PASO DE MENSAJES
MODELO PASO DE MENSAJES
 
Python workshop
Python workshopPython workshop
Python workshop
 
TUTORIAL JAVA
TUTORIAL JAVATUTORIAL JAVA
TUTORIAL JAVA
 
Bases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCBases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBC
 
JAVA.PPT
JAVA.PPTJAVA.PPT
JAVA.PPT
 

Último

Fijación, transporte en camilla e inmovilización de columna cervical II​.pptx
Fijación, transporte en camilla e inmovilización de columna cervical II​.pptxFijación, transporte en camilla e inmovilización de columna cervical II​.pptx
Fijación, transporte en camilla e inmovilización de columna cervical II​.pptx
janetccarita
 
FICHA 7- crecimiento económico desarrollo de la sociedad
FICHA  7- crecimiento económico desarrollo de la sociedadFICHA  7- crecimiento económico desarrollo de la sociedad
FICHA 7- crecimiento económico desarrollo de la sociedad
maldonadoretamozoc
 
Bianchi-2005-Historia-social-del-mundo-occidental.pdf
Bianchi-2005-Historia-social-del-mundo-occidental.pdfBianchi-2005-Historia-social-del-mundo-occidental.pdf
Bianchi-2005-Historia-social-del-mundo-occidental.pdf
perezcandela938
 
Seguridad Documental unne Criminalisticas catedra de documentologia 1
Seguridad Documental unne Criminalisticas catedra de documentologia 1Seguridad Documental unne Criminalisticas catedra de documentologia 1
Seguridad Documental unne Criminalisticas catedra de documentologia 1
911Busisness911
 
Los 20 medicamentos más recetados de
Los      20 medicamentos más recetados deLos      20 medicamentos más recetados de
Los 20 medicamentos más recetados de
prodinetpc1
 
SEMANA 10 - ADHESION CELULAR / BIOLOGÍA CELULAR
SEMANA 10 - ADHESION CELULAR  / BIOLOGÍA CELULARSEMANA 10 - ADHESION CELULAR  / BIOLOGÍA CELULAR
SEMANA 10 - ADHESION CELULAR / BIOLOGÍA CELULAR
JeanAbreguParedes
 
TEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
TEORIAS DE LA EVOLUCION LAMARCK Y DARWINTEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
TEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
DesignDreams1
 
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdfLIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
MelissaHorna
 
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de..."Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
AlexanderZrate2
 
La doble vida del ATP. DIEGO GOMEZ.pdf 123
La doble vida del ATP. DIEGO GOMEZ.pdf 123La doble vida del ATP. DIEGO GOMEZ.pdf 123
La doble vida del ATP. DIEGO GOMEZ.pdf 123
DiegoGomez400963
 
Heterociclos; pequeñas y maravillosas estructuras-Química
Heterociclos; pequeñas y maravillosas estructuras-QuímicaHeterociclos; pequeñas y maravillosas estructuras-Química
Heterociclos; pequeñas y maravillosas estructuras-Química
PriyaQuijano
 
Atlas de la biodiversidad en Colombia América del sur
Atlas de la biodiversidad en Colombia América del surAtlas de la biodiversidad en Colombia América del sur
Atlas de la biodiversidad en Colombia América del sur
ssuser101841
 
Calor, tema de termodinamica en fisica para preparatoria
Calor, tema de termodinamica en fisica para preparatoriaCalor, tema de termodinamica en fisica para preparatoria
Calor, tema de termodinamica en fisica para preparatoria
rubentzompaangeles
 
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVOENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
hausofcaba
 
Virus de la Inmunodeficiencia humana (VIH).pdf
Virus de la Inmunodeficiencia humana (VIH).pdfVirus de la Inmunodeficiencia humana (VIH).pdf
Virus de la Inmunodeficiencia humana (VIH).pdf
melaniepalomino1502
 
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
AugustoBrizola
 
Mapa-conceptual-del-Metabolismo. .........
Mapa-conceptual-del-Metabolismo. .........Mapa-conceptual-del-Metabolismo. .........
Mapa-conceptual-del-Metabolismo. .........
luztania508
 
Breve y corta presentación sobre la Cardiologia
Breve y corta presentación sobre la CardiologiaBreve y corta presentación sobre la Cardiologia
Breve y corta presentación sobre la Cardiologia
gtelloortiz2
 
NEUROQUIMICA es la informacion de como funciona la neuroquimica
NEUROQUIMICA es la informacion de como funciona la neuroquimicaNEUROQUIMICA es la informacion de como funciona la neuroquimica
NEUROQUIMICA es la informacion de como funciona la neuroquimica
DanielNava80
 
35 WAIS III Manual de administracion y puntuacion 1.pdf
35 WAIS III Manual de administracion y puntuacion 1.pdf35 WAIS III Manual de administracion y puntuacion 1.pdf
35 WAIS III Manual de administracion y puntuacion 1.pdf
JessicaNuez61
 

Último (20)

Fijación, transporte en camilla e inmovilización de columna cervical II​.pptx
Fijación, transporte en camilla e inmovilización de columna cervical II​.pptxFijación, transporte en camilla e inmovilización de columna cervical II​.pptx
Fijación, transporte en camilla e inmovilización de columna cervical II​.pptx
 
FICHA 7- crecimiento económico desarrollo de la sociedad
FICHA  7- crecimiento económico desarrollo de la sociedadFICHA  7- crecimiento económico desarrollo de la sociedad
FICHA 7- crecimiento económico desarrollo de la sociedad
 
Bianchi-2005-Historia-social-del-mundo-occidental.pdf
Bianchi-2005-Historia-social-del-mundo-occidental.pdfBianchi-2005-Historia-social-del-mundo-occidental.pdf
Bianchi-2005-Historia-social-del-mundo-occidental.pdf
 
Seguridad Documental unne Criminalisticas catedra de documentologia 1
Seguridad Documental unne Criminalisticas catedra de documentologia 1Seguridad Documental unne Criminalisticas catedra de documentologia 1
Seguridad Documental unne Criminalisticas catedra de documentologia 1
 
Los 20 medicamentos más recetados de
Los      20 medicamentos más recetados deLos      20 medicamentos más recetados de
Los 20 medicamentos más recetados de
 
SEMANA 10 - ADHESION CELULAR / BIOLOGÍA CELULAR
SEMANA 10 - ADHESION CELULAR  / BIOLOGÍA CELULARSEMANA 10 - ADHESION CELULAR  / BIOLOGÍA CELULAR
SEMANA 10 - ADHESION CELULAR / BIOLOGÍA CELULAR
 
TEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
TEORIAS DE LA EVOLUCION LAMARCK Y DARWINTEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
TEORIAS DE LA EVOLUCION LAMARCK Y DARWIN
 
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdfLIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
LIBRO-Biologia De Hongos (Cepero de García et al.) .pdf
 
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de..."Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
"Abordando la Complejidad de las Quemaduras: Desde los Orígenes y Factores de...
 
La doble vida del ATP. DIEGO GOMEZ.pdf 123
La doble vida del ATP. DIEGO GOMEZ.pdf 123La doble vida del ATP. DIEGO GOMEZ.pdf 123
La doble vida del ATP. DIEGO GOMEZ.pdf 123
 
Heterociclos; pequeñas y maravillosas estructuras-Química
Heterociclos; pequeñas y maravillosas estructuras-QuímicaHeterociclos; pequeñas y maravillosas estructuras-Química
Heterociclos; pequeñas y maravillosas estructuras-Química
 
Atlas de la biodiversidad en Colombia América del sur
Atlas de la biodiversidad en Colombia América del surAtlas de la biodiversidad en Colombia América del sur
Atlas de la biodiversidad en Colombia América del sur
 
Calor, tema de termodinamica en fisica para preparatoria
Calor, tema de termodinamica en fisica para preparatoriaCalor, tema de termodinamica en fisica para preparatoria
Calor, tema de termodinamica en fisica para preparatoria
 
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVOENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
ENZIMAS ANALISIS CUALITATIVO Y CUANTITATIVO
 
Virus de la Inmunodeficiencia humana (VIH).pdf
Virus de la Inmunodeficiencia humana (VIH).pdfVirus de la Inmunodeficiencia humana (VIH).pdf
Virus de la Inmunodeficiencia humana (VIH).pdf
 
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
0.1 SEMIOLOGIA neurologica.ppjjjjjjjjjjk
 
Mapa-conceptual-del-Metabolismo. .........
Mapa-conceptual-del-Metabolismo. .........Mapa-conceptual-del-Metabolismo. .........
Mapa-conceptual-del-Metabolismo. .........
 
Breve y corta presentación sobre la Cardiologia
Breve y corta presentación sobre la CardiologiaBreve y corta presentación sobre la Cardiologia
Breve y corta presentación sobre la Cardiologia
 
NEUROQUIMICA es la informacion de como funciona la neuroquimica
NEUROQUIMICA es la informacion de como funciona la neuroquimicaNEUROQUIMICA es la informacion de como funciona la neuroquimica
NEUROQUIMICA es la informacion de como funciona la neuroquimica
 
35 WAIS III Manual de administracion y puntuacion 1.pdf
35 WAIS III Manual de administracion y puntuacion 1.pdf35 WAIS III Manual de administracion y puntuacion 1.pdf
35 WAIS III Manual de administracion y puntuacion 1.pdf
 

Getting deeper with TPL & async (Spanish version)

  • 2. Temas: • TPL • Paralelización de código imperativo. • Programación Paralela con tareas(Task). • Colecciones de Concurrencia y Pipelines. • Estructuras para la coordinación de los datos. • Async
  • 4. • Paralelización de código imperativo •Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . • Programación Paralela con tareas(Task) •Task, TimeOuts, Cancelando, Excepciones, Retornando valores. • Colecciones de Concurrencia y Pipelines •ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, ConcurrentDictionary.
  • 5. Parallel Class ( System.Threading.Tasks ) Parallel.For Parallel.ForEach Parallel.Invoke
  • 6. Parallel.Invoke La manera más simple de paralelizar varios métodos. Sintaxis: Invoke( Action [] ) Invoke( ParallelOptions, Action [] ) No se tiene garantía de orden. No retorna hasta que cada invocación no hay finalizado. GoToRiver GoToPark GoToZoo GoToPlainArea Parallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea); Parallel.Invoke( () => Walk.GoToPark("Santiago"), Walk.GoToRiver, delegate() { Walk.GoToZoo("26st"); }, Walk.GoToPlainArea); Patrón Fork/Join
  • 7. 3 posibles escenarios de paralelismo Escenario Ideal Ejemplo hipotético con una arquitectura con 4 núcleos lógicos. 1era ejecución GoToZoo GoToRiver GoToPark GoToPlainArea 2da ejecución GoToPark GoToRiver GoToPlainArea GoToZoo 3era ejecución GoToZoo GoToPlainArea GoToRiver GoToPark
  • 8. Ventajas y Desventajas 1. Es un método muy simple de lograr paralelismo sin tareas, ni hilos. 1. Métodos con notables diferencias en cuanto al tiempo de ejecución. 2. Cada llamada crea una sobrecarga antes de correr los métodos. 3. Como todo código en paralelo, esta expuesto a existencias de interdependencia e incontrolables interacciones. 4. No tiene garantía de orden.
  • 9. Análisis de tiempo con respecto al secuencial Walk.GoToPark(); Walk.GoToRiver(); Walk.GoToZoo(); Walk.GoToPlainArea(); Ejemplo hipotético (figuras)con una arquitectura con 4 núcleos lógicos y mediciones con 2 núcleos lógicos Parallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea);
  • 10. Parallel.For Versión paralelizada del clásico for. Sintaxis: For( Int32, Int32, Action<Int32> ) For( Int32, Int32, Action<Int32, ParallelLoopState> ) List<string> data = new List<string>(){"Estamos","paralelizando","el","for","y","el","foreach"}; Tradicional Paralelizado for (int i = 0; i < data.Count; i++) { Console.Write(i); } Parallel.For(0, data.Count, x => { Console.Write(x); }); No tiene por que cumplirse el orden. Tener en cuenta si los elementos estan relacionados entre si. Desde LowerBound a UpperBound. El primer parámetro es inclusivo, el segundo exclusivo. Load- Balance Pequeños bodies.
  • 11. Análisis de tiempo con respecto al secuencial(RayTracing) void Render(Scene scene, Color[,] rgb) { for (int y = 0; y < screenHeight; y++) { for (int x = 0; x < screenWidth; x++) rgb[x,y] = TraceRay(new Ray(scene,x,y)); } } void Render(Scene scene, Color[,] rgb) { Parallel.For(0, screenHeight, delegate(int y) { for (int x = 0; x < screenWidth; x++) rgb[x,y] = TraceRay(new Ray(scene,x,y)); }); } Ocho núcleos y 350 x 350 Secuencial: 1.7 fps Paralelo : 12 fps Dos núcleos y 350 x 350 Secuencial: 1.0 fps Paralelo : 2.0 fps Dos núcleos y 578 x 485 Secuencial: 0.5 fps Paralelo : 1.0 fps
  • 12. Análisis de tiempo con respecto al secuencial(Primos) List<int> primes = new List<int>(); int cotaSup = 50000; for (int i = 2; i < cotaSup; i++) { if (isPrime(i)) primes.Add(i); } Parallel.For(2, cotaSup, (i) => { if (isPrime(i)) primes.Add(i); }); 0.5 segundos 0.2 segundos 0.5/0.2 = 2.5x Ejemplo hipotético (figuras)con una arquitectura con 4 núcleos lógicos y mediciones con 2 núcleos lógicos
  • 13. F# let sentences = [|"Estamos"; "paralelizando"; "el"; "for"; "y"; "el"; "foreach"|] for index=0 to sentences.Length do printfn "%d" index printfn "" let accion indice = printfn "%d" indice Parallel.For(0,sentences.Length, new Action<int>(accion)) Console.ReadKey();
  • 14. Parallel.ForEach Versión paralelizada del clásico foreach. Sintaxis: ForEach <TSource>( IEnumerable <TSource>, Action <TSource> ) ForEach <TSource>( IEnumerable <TSource>, Action <TSource, ParallelLoopState> ) List<string> data = new List<string>(){"Estamos","paralelizando","el","for","y","el","foreach"}; foreach (var items in data) { Console.Write(items + " "); } Tradicional Paralelizado Parallel.ForEach(data, x => { Console.Write(x + " "); });
  • 15. Análisis de tiempo con respecto al secuencial Ejemplo hipotético (figuras)con una arquitectura con 4 núcleos lógicos y mediciones con 2 núcleos lógicos foreach (var i in inputData) { if (isPrime(i)) resultData[indice] = i; indice++; } 28 segundos 14 segundos var op = Partitioner.Create(inputData); Parallel.ForEach(op, (item, loopState, index) => { 28/14 = 2x if (isPrime(item)) resultData[index] = item; });
  • 16. ¿Como paramos los ciclos?(Cancelando) ParallelLoopState ParallelLoopResult ParallelLoopResult loopResult1 = Parallel.For(0, 10, (x, state) => { if (x < 5) Console.WriteLine(x); else state.Stop(); }); ParallelLoopResult loopResult2 = Parallel.ForEach(data, (x, state) => { if (!x.Equals("y")) Console.WriteLine(x); else state.Break(); }); Console.WriteLine(loopResult1.LowestBreakIteration); Console.WriteLine(loopResult1.IsCompleted); Console.WriteLine(loopResult2.LowestBreakIteration); Console.WriteLine(loopResult2.IsCompleted);
  • 17. Manejo de Excepciones AggregateException Formato: try { ..... ..... } catch (AggregateException aggEx) { foreach (Exception ex in aggEx.InnerExceptions) { Console.WriteLine(string.Format("Caught exception '{0}'",ex.Message)); } }
  • 18. Manejo de Excepciones Ejemplo: try { ParallelLoopResult loopResult = Parallel.For(0, 10, (x, state) => { if (x < 5) Console.WriteLine(x); else { var ex = "Excepción en el índice " + x; throw new InvalidDataException(ex); } }); Console.WriteLine("Ciclo for completado: {0}", loopResult.IsCompleted); } catch (AggregateException aggEx) { foreach (var innerException in aggEx.InnerExceptions) { //Pueden haber 2 excepciones a causa del paralelismo. Console.WriteLine("Excepcion capturada: " + innerException.Message); } }
  • 19. ParallelOptions ParallelOptions.MaxDegreeOfParallelism ParallelOptions.TaskScheduler ParallelOptions.CancellationToken Se utilizan en los métodos de Parallel. var source = Enumerable.Range(8, 2000).ToArray(); double[] result = new double[source.Length]; ParallelOptions parallelOptions = new ParallelOptions(); parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount*2; //Ejemplo Parallel.ForEach(Partitioner.Create(8, source.Length),parallelOptions, range => { for (int i = range.Item1; i < range.Item2; i++) result[i] = source[i]*Math.E; });
  • 20. Particionando Partición por rangos Partición por bloques Partitioner.Create(1,40) Parallel.ForEach(Partitioner.Create(10, 200), range => { Console.WriteLine("{0},{1}",range.Item1,range.Item2); for (int i = range.Item1; i < range.Item2; i++) { data[i] = data[i]*i; } }); Optimizando el particionado según el número de núcleos. Partitioner.Create(1,40, ((numeroDeElementos /numeroDeNucleos)+1)) System.Environment.ProcessorCount Sintaxis: Create <TSource >( IEnumerable<TSource > ) Create ( Int32, Int32) Create ( Int32, Int32, Int32)
  • 21. • Paralelización de código imperativo •Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . • Programación Paralela con tareas(Task) •Task, TimeOuts, Cancelando, Excepciones, Retornando valores. • Parallel Linq (PLinq) •Operadores, Cancelando, Agregaciones, Excepciones. • Colecciones de Concurrencia y Pipelines •ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, ConcurrentDictionary.
  • 22. Task
  • 24. Ciclo de vida y estado de una tarea EnumTaskStatus Miembros: Created WaitingForActivation WaitingToRun Running WaitingForChildrenToComplete RanToCompletion Canceled Faulted
  • 25. Invocando Tareas GenerateSomething GenerateNothing Parallel.Invoke(GenerateSomething,() => GenerateNothing()); //Los métodos no están corriendo todavía, pero las tareas están listas para empezar. //El estado para ambas tareas es TaskStatus.Created. var task1 = new Task(GenerateSomething); var task2 = new Task(() => GenerateNothing()); task1.Start(); task2.Start(); Task.WaitAll(task1, task2); var task1 = Task.Factory.StartNew(() => GenerateNothing());
  • 26. TimeOuts var task1 = new Task(GenerateSomethingTimeOut); var task2 = new Task(() => GenerateNothing()); task1.Start(); task2.Start(); if(!Task.WaitAll(new Task[]{task1,task2},300)) { Console.WriteLine("GenerateSomething y GenerateNothing han tardado más de 300ms"); } if(!task1.Wait(300)) { Console.WriteLine("GenerateSomething ha tardado más de 300ms"); }
  • 27. Manejando excepciones con las Task static void GenerateSomethingCancel(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine("GenerateSomething"); Thread.Sleep(3000); if (sw.Elapsed.Seconds > 1) throw new TimeoutException("La tarea se demoró mas de 1 segundos"); cancellationToken.ThrowIfCancellationRequested(); } try { // Espera por que todas las tareas finalicen en menos de 3 segundos if (!Task.WaitAll(new Task[] { task1, task2 }, 3000)) { Console.WriteLine("GenerateSomething y GenerateNothing han tardado más de 300ms en terminar"); Console.WriteLine(task1.Status.ToString()); Console.WriteLine(task2.Status.ToString()); } } catch (AggregateException ex) { foreach (Exception innerEx in ex.InnerExceptions) { Console.WriteLine(innerEx.ToString()); } }
  • 28. Retornando valores desde las tareas static List<string> GenerateSomethingReturn() { Console.WriteLine("GenerateSomething"); Thread.Sleep(3000); return new List<string>{"Estoy","retornando","una","lista","de","strings."}; } var task1 = Task.Factory.StartNew(() => GenerateSomethingReturn()); try { task1.Wait(); } catch (AggregateException ex) { foreach (Exception innerEx in ex.InnerExceptions) { Console.WriteLine(innerEx.ToString()); } } var task2 = Task.Factory.StartNew(() => { foreach (var result in task1.Result) { Console.WriteLine(result); } });
  • 29. Cancelando Tareas usando Tokens CancellationToken cancellationToken CancellationTokenSource Se pasa como parámetro Controla la cancelación desde el método principal static void GenerateSomethingCancel(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Console.WriteLine("GenerateSomething"); Thread.Sleep(3000); cancellationToken.ThrowIfCancellationRequested(); } var cts = new CancellationTokenSource(); var ct = cts.Token; var task1 = Task.Factory.StartNew(() => GenerateNothingCancel(ct),ct); cts.Cancel(); if (task1.IsCanceled) { Console.WriteLine("La Tarea GenerateSomethingCancel que estaba en ejecucion fue cancelada"); }
  • 30. TaskCreationOptions Optimizando el código TaskCreationOptions.AttachedToParent TaskCreationOptions.None TaskCreationOptions.LongRunning TaskCreationOptions.PreferFairness var task2 = Task.Factory.StartNew(() => Ayudar al Scheduler { foreach (var result in task1.Result) { Console.WriteLine(result); } },TaskCreationOptions.PreferFairness);
  • 31. Concatenando múltiples tareas usando Continuación try { var task1 = Task.Factory.StartNew(() => GenerateSomethingCancelReturn(ct), ct); var task2 = task1.ContinueWith(t => { foreach (var result in t.Result) { Console.WriteLine(result); } }); task1.Wait(); } catch (AggregateException ex) { foreach (Exception innerEx in ex.InnerExceptions) { Console.WriteLine(innerEx.ToString()); } } var task2 = Task.Factory.StartNew(() => { foreach (var result in task1.Result) { Console.WriteLine(result); } });
  • 32. var f = Task.Factory; var build1 = f.StartNew(() => Build(project1)); var build2 = f.StartNew(() => Build(project2)); var build3 = f.StartNew(() => Build(project3)); var build4 = build1.ContinueWith(() => Build(project4)); var build5 = f.ContinueWhenAll(new[] { build1, build2, build3 }, () => Build(project5)); var build6 = f.ContinueWhenAll(new[] { build3, build4 }, () => Build(project6)); var build7 = f.ContinueWhenAll(new[] { build5, build6 }, () => Build(project7)); var build8 = build5.ContinueWith(() => Build(project8)); Task.WaitAll(build1, build2, build3, build4, build5, build6, build7, build8);
  • 33. Mezclando paralelismo y código secuencial con Continuación
  • 34. TaskContinuationOptions TaskContinuationOptions.AttachedToParent TaskContinuationOptions.ExecuteSynchronously TaskContinuationOptions.LongRunning TaskContinuationOptions.PreferFairness TaskContinuationOptions.None TaskContinuationOptions.NotOnCanceled TaskContinuationOptions.NotOnFaulted TaskContinuationOptions.NotOnRanToCompletion TaskContinuationOptions.OnlyOnCanceled TaskContinuationOptions.OnlyOnFaulted TaskContinuationOptions.OnlyOnRanToCompletion var task2 = task1.ContinueWith(t => { foreach (var result in t.Result) { Console.WriteLine(result); } },TaskContinuationOptions.None); Especificando el comportamiento de la próxima tarea Condicionando la próxima tarea
  • 35. Análisis de tiempo con respecto a los Thread Ejemplo hipotético con una arquitectura con 2 núcleos lógicos. 64 Threads versus 64 Tasks 1. Los primos hasta el 50 : Thread 0.9 segundos. Tasks 0.2 segundos. 2. Los primos hasta el 500 : Thread 2 segundos. Tasks 1 segundo. 3. Los primos hasta el 5000 : Thread 15 segundos. Tasks 13 segundos. 4. Los primos hasta el 50000: Thread 116 segundos. Tasks 104 segundos.
  • 36. • Paralelización de código imperativo •Parallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . • Programación Paralela con tareas(Task) •Task, TimeOuts, Cancelando, Excepciones, Retornando valores. • Colecciones de Concurrencia y Pipelines •ConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection, ConcurrentDictionary.
  • 37. var data = new List<int>(); Parallel.ForEach(Partitioner.Create(0, 200), range => { for (int i = range.Item1; i < range.Item2; i++) lock (data) data.Add(i); }); data.ForEach(x => Console.Write(x + " ")); Solución
  • 38. Colecciones Thread-Unsafe: System.Collections System.Collections.Generic Colecciones Thread-Safe: System.collections.Concurrent ConcurrentQueue<T> ConcurrentStack<T> ConcurrentBag<T> ConcurrentDictionary<TKey, TValue> BlockingCollection<T> IProducerConsumerCollection<T>
  • 39. Colecciones de concurrencia ideales para escenarios productor-consumidor.
  • 40. ConcurrentQueue<T> Lock-Free Métodos Importantes: Enqueue TryDequeue TryPeek
  • 41. ConcurrentQueue<T> -Esta coleccion es completamente libre de lock (lock-free) -Usa compare and swap (CAS) -Cuando falla una operacion CAS se pone en estado de contencion.
  • 42. ConcurrentQueue<T> -Produce (over-head). -Mejora el rendimiento de la cola y otras colecciones thread-unsafe, en determinados escenarios. -Nos facilita el trabajo con la concurrencia.
  • 43. ConcurrentQueue<T> Caracteristicas importantes: concurrentQueue.Enqueue(item); if (concurrentQueue.TryPeek(out item)) { DoSomething(item); } if (concurrentQueue.TryDequeue(out item)) { DoSomething(item); }
  • 46. ConcurrentStack<T> -Similar a la coleccion ConcurrentQueue. -Es una coleccion LIFO. -Atomicidad en los metodos PushRange y PopRange reduce la cantidad de insersiones y extracciones concurrentes en la coleccion.
  • 47. ConcurrentStack<T> Caracteristicas importantes: concurrentStack.Push(item); if (concurrentStack.TryPeek(out item)) { DoSomething(item); } if (concurrentStack.TryPop(out item)) { DoSomething(item); }
  • 48. ConcurrentStack<T> Caracteristicas importantes: Parallel.ForEach(Partitioner.Create(0, partCount), p => { concurrentStack.PushRange ( numberArray, p.Item1, p.Item2 - p.Item1 ); });
  • 49. ConcurrentStack<T> Sintaxis: count = s.TryPopRange(numberArray, 0, numberArray.Length); count = s.TryPopRange(numberArray); Count sera la cantidad de objetos que fueron sacados del tope de la cola e insertados el el array.
  • 50. TPL - Colecciones de Concurrencia y Pipelines Atomiciadad o costo… PushRange TryPopRange Push TryPop Buen rendimiento Igual concurrencia No Over-Head No memoria adicional Over-Head Memoria adicional Atomiciadad Menor concurrencia
  • 51. ConcurrentBag<T> Métodos Importantes: Add TryTake TryPeek Nota: Colección donde el orden no importa. Ideal para escenarios Productor – Consumidor.
  • 52. ConcurrentBag<T> -Ideal para ciertos escenarios productor-consumidor. -No es completamente lock-free. -Bastante ineficiente, donde el hilo productor es distinto al consumidor. -Mantiene una cola local para cada hilo que accede a ella.
  • 53. ConcurrentBag<T> Caracteristicas importantes: sentencesBag.Add(s.ToString()); string sentence; if (_sentencesBag.TryTake(out sentence)) { _capWordsInSentencesBag.Add ( CapitalizeWords(delimiterChars, sentence, '' )); }
  • 54. BlockingCollection<T> Métodos Importantes: Add TryAdd Take TryTake CompleteAdding GetConsumerEnumerable Ofrece soporte para Bounding y Blocking. Ideal para escenarios Productor – Consumidor. Ideal para implementaciones de pipelines. Capacidad máxima opcional. Permite cancelación a través de tokens. Es un wrapper para una interfaz del tipo IProducerConsumerCollection<T> Existen 2 tipos de enumeraciones con foreach: 1. Enumeración de solo lectura. 2. Enumeración que elimina los elementos que han sido enumerados(P-C).
  • 55. BlockingCollection<T> Caracteristicas importantes: BlockingCollection<int> stackBC = new BlockingCollection<int> (new ConcurrentStack<int>()); BlockingCollection<int> bagBC = new BlockingCollection<int> (new ConcurrentBag<int>()); BlockingCollection<int> bc = new BlockingCollection<int>(count);
  • 56. BlockingCollection<T> Caracteristicas importantes: IsCompleted, IsAddingCompleted. string aux; while (!sentences.IsCompleted) { if (sentences.TryTake(out aux)) upperSentences.Add(aux.ToUpper()); } upperSentences.CompleteAdding();
  • 57. BlockingCollection<T> Caracteristicas importantes: GetConsumingEnumerable() foreach (var item in upperSentences.GetConsumingEnumerable()) { finalSentences.Add(item.Replace("U", "")); } upperSentences.CompleteAdding();
  • 58. BlockingCollection<T> Caracteristicas importantes: if (!_sentencesBC.TryAdd(newSentence, 2000, cancToken)) { throw new TimeoutException( "_sentencesBC took more than 2 seconds to add an item"); } catch (OperationCanceledException ex) { // The operation was cancelled break; }
  • 59. BlockingCollection<T> Caracteristicas importantes: BlockingCollection<TOutput>.AddToAny(Output, result, _token); BlockingCollection<TOutput>.TryAddToAny(Output, result, timeOut, _token);
  • 60. BlockingCollection<T> Caracteristicas importantes: BlockingCollection<TOutput>.AddToAny(array, item, _token); BlockingCollection<TOutput>.TryAddToAny(array, item, timeOut, _token); Estos metodos devuelven el indice de la coleccion, en el array de colecciones, a la cual se le agrego el elemento.
  • 61. BlockingCollection<T> Caracteristicas importantes: BlockingCollection<TOutput>.TakeFromAny(array, out item, _token); BlockingCollection<TOutput>.TakeFromAny(array, out item, timeOut, _token); Estos metodos devuelven el indice de la coleccion, en el array de colecciones, de la cual se elimino el elemento.
  • 62. BlockingCollection<T> -Facilita el trabajo con las colecciones thread-safe. -Produce Over-Head. -Disminuye la cantidad y simplfica la complejidad del codigo. -Ideal para la implementacion de pipelines(Ejemplo)
  • 63. ConcurrentDictionary<T> Lock-Free para operaciones de lectura Métodos Importantes: AddOrUpdate GetEnumerator GetOrAdd TryAdd TryGetValue TryRemove TryUpdate Sintaxis: ConcurrentDictionary<TKey, TValue >() ConcurrentDictionary<TKey, TValue >(Int32, Int32) int initialCapacity = 100; int concurrencyLevel = Environment.ProcessorCount * 2; ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity); for (int i = 0; i < 64; i++) cd[i] = i * i; Console.WriteLine(“23² is {0} (should be {1})", cd[23], 23 * 23);
  • 64. ConcurrentDictionary<Tkey, TValue> Caracteristicas importantes: _rectanglesDict.AddOrUpdate( newKey, newRect, (key, existingRect) => {if (existingRect != newRect) { lock (existingRect) { existingRect.Update( newRect.Location, newRect.Size); } return existingRect; } else { return existingRect; } });
  • 65.
  • 66. Asynchronous Programming Model(APM) Event-based Asynchronous Pattern(EAP) Task Asynchronous Pattern(TAP) Patrones estándares Idea Sincrónico = Asincrónico TAP APM EAP
  • 67. Microsoft Visual Studio AsyncCommunity Technology Preview (CTP). ( Visual Studio Async CTP ) Nuevas keywords: async: await: Marca a métodos o expresiones lambdas como asincrónicas. Retiene el control hasta que la operación asincrónica termine. Objetivo: Programación asincrónica = Programación sincrónica. Escribir códigos simples y fáciles de entender. Fin de los métodos callback.
  • 68. public int SumPageSizes(IList<Uri> uris) { int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = new WebClient().DownloadData(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); return total; } Versión Sincrónica Problemas: Bloquea la interfaz de usuario. No nos va enseñando el estado de la descarga. Solución Versión Asincrónica
  • 69. Versión Asíncrona con EAP public void SumPageSizesAsync(IList<Uri> uris) { SumPageSizesAsyncHelper(uris.GetEnumerator(), 0); } private void SumPageSizesAsyncHelper(IEnumerator<Uri> enumerator, int total) { if (enumerator.MoveNext()) { statusText.Text = string.Format("Found {0} bytes ...", total); var client = new WebClient(); client.DownloadDataCompleted += (sender, e) => SumPageSizesAsyncHelper(enumerator, total + e.Result.Length); client.DownloadDataAsync(enumerator.Current); } else { statusText.Text = string.Format("Found {0} bytes total", total); enumerator.Dispose(); } } Problemas: Hay que romper el foreach. En cada llamado se ancla un evento. El código es recursivo. No retorna el total una ves calculado.
  • 70. Conclusiones El método anterior es asincrónico con una sola llamada asincrónica y una sola estructura de control alrededor de esta. Imagínense más llamadas asincrónicas y más estructuras de control, sería un verdadero caos. Primera solución: Utilizar APM o EAP con las nuevas clases de TPL. Segunda solución: Utilizar TAP(junto a async). public async Task<int> SumPageSizesAsyncBest(IList<Uri> uris) { int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = await new WebClient().DownloadDataTaskAsync(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); listBox1.Items.Add(total.ToString()); return total; }
  • 71. let asyncProcessFile (filePath : string) = async { printfn "Procesando fichero [%s]" (Path.GetFileName(filePath)) use fileStream = new FileStream(filePath,FileMode.Open) let bytesToRead = int fileStream.Length let! data = fileStream.AsyncRead(bytesToRead) //Returna un objeto Async<byte[]> printfn “Se leyeron [%d] bytes" data.Length use resultFile = new FileStream(filePath + ".results", FileMode.Create) do! resultFile.AsyncWrite(data,0,data.Length) printfn "Finalizado el procesamiento del archivo [%s]" <| Path.GetFileName(filePath) } |> Async.Start asyncProcessFile "./testAsync.txt" Console.ReadKey(); async en F#
  • 72. Retorno public async void SumPageSizesAsyncBestOther(IList<Uri> uris){ int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = await new WebClient().DownloadDataTaskAsync(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); listBox1.Items.Add(total.ToString()); } ( Fire and forget ) private async void sumButton_Click(object sender, RoutedEventArgs e) { sumButton.IsEnabled = false; await SumPageSizesAsync(GetUrls())); sumButton.IsEnabled = true; } ( Incluyendo genéricas)
  • 73. Código final propuesto public async Task<int> SumPageSizesAsyncBetter(IList<Uri> uris) { var tasks = from uri in uris select new WebClient().DownloadDataTaskAsync(uri); var data = await TaskEx.WhenAll(tasks); return await TaskEx.Run(() =>data.Sum(s => s.Length)); } Nota: Se propone incluir Run() y WhenAll() en la claseTask cuando async arrive a su versión final; mientras este en CTP se alojarán en una clase de prueba llamada TaskEx.
  • 74. ¿Como funciona async? Original Transformado por el compilador public static async Task DoSum(int from,int to) { int result = await Sum(from, to); string param = result.ToString() + "rn"; File.AppendAllText(@"./result.txt", param); } public static Task<int> Sum(int from, int to) { Task<int> sum = TaskEx.Run(() => { int result = 0; for (int i = from; i <= to; i++) { TaskEx.Delay(500); result += i; } return result; }); return sum; } public static Task DoSum(int from,int to) { var task1 = Task.Factory.StartNew(() => Sum(from,to)); return task1.ContinueWith((antecedentTask) => { string param = antecedentTask.Result.Result.ToString() + rn"; File.AppendAllText(@"./result.txt", param); }); } public static Task<int> Sum(int from, int to) { Task<int> sum = TaskEx.Run(() => { int result = 0; for (int i = from; i <= to; i++) { TaskEx.Delay(500); result += i; } return result; }); return sum; }
  • 75. Como funciona async static void Main(string[] args) { public static async Task DoSum(int from,int to) { int result = await Sum(from, to); string param = result.ToString() + "rn"; File.AppendAllText(@"./result.txt", param); } int number; string input; Task myTask = new Task(Console.WriteLine); while (true) { Console.WriteLine("Entre un número: "); input = Console.ReadLine(); if (string.Empty == input) break; number = int.Parse(input); myTask = DoSum(1, number); } myTask.Wait(); } Continua la ejecución. Retorna una tarea Callback En cuanto la tarea finalice.
  • 76. public async Task<int> SumPageSizesAsyncBest(IList<Uri> uris) { int total = 0; foreach (var uri in uris) { statusText.Text = string.Format("Found {0} bytes ...", total); var data = await new WebClient().DownloadDataTaskAsync(uri); total += data.Length; } statusText.Text = string.Format("Found {0} bytes total", total); listBox1.Items.Add(total.ToString()); return total; } Retornando valores desde async
  • 77. Cancelación desde async C# F# public async void Inicio(Program program) { cts = new CancellationTokenSource(); program.Hola(cts.Token); Thread.Sleep(1000); if (cts != null) cts.Cancel(); } public async Task Hola(CancellationToken ct) { Console.WriteLine("Before await"); await TaskEx.Delay(5000); ct.ThrowIfCancellationRequested(); Console.WriteLine("After await"); } let cancelableTask = async { printfn "Waiting 10 seconds..." for i = 1 to 10 do printfn "%d..." i do! Async.Sleep(1000) printfn "Finished!" } // Callback used when the operation is canceled let cancelHandler (ex : OperationCanceledException) = printfn "The task has been canceled." Async.TryCancelled(cancelableTask,cancelHandler) |>Async.Start Thread.Sleep(2000) Async.CancelDefaultToken()
  • 78. Excepciones desde async try { string txt = await w.DownloadStringTaskAsync(url); } catch(WebException x) { --- Handle exception. } let asyncOperation = async { try // ... with | :? IOException as ioe -> printfn "IOException: %s" ioe.Message | :? ArgumentException as ae -> printfn "ArgumentException: %s" ae.Message } Las excepciones se manejan igual que de manera sincrónica.

Notas del editor

  1. Parallel Class, provee soporte para paralelizar facilmente ciclos y regiones.
  2. Parallel Class, provee soporte para paralelizar fácilmente ciclos y regiones.
  3. Parallel Class, provee soporte para paralelizar fácilmente ciclos y regiones.
  4. Parallel Class, provee soporte para paralelizar fácilmente ciclos y regiones.
  5. Parallel Class, provee soporte para paralelizar fácilmente ciclos y regiones.