private async Task RealizarPruebaMatrices(int maximoGradoParalelismo) { int colCount = 2508; int rowCount = 1300; int colCount2 = 1850; double[,] m1 = Matrices.InicializarMatriz(rowCount, colCount); double[,] m2 = Matrices.InicializarMatriz(colCount, colCount2); double[,] result = new double[rowCount, colCount2]; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { await Task.Run(() => { Matrices.MultiplicarMatricesParalelo(m1, m2, result, cancellationTokenSource.Token, maximoGradoParalelismo); }); Console.WriteLine($"Maximo grado: {maximoGradoParalelismo}; tiempo: {stopwatch.ElapsedMilliseconds / 1000.0}"); } catch (Exception ex) { Console.WriteLine("Operación Cancelada"); } finally { cancellationTokenSource.Dispose(); } }
private async void btnIniciar_Click(object sender, EventArgs e) { // contexto de sincronizacion //Console.WriteLine($"hilo antes del await: {Thread.CurrentThread.ManagedThreadId}"); //await Task.Delay(500); //Console.WriteLine($"hilo despues del await: {Thread.CurrentThread.ManagedThreadId}"); // await ObtenerSaludo2("Edison"); ////configureAwait //CheckForIllegalCrossThreadCalls = true; //btnCancelar.Text = "antes"; //await Task.Delay(1000).ConfigureAwait(continueOnCapturedContext: false); //btnCancelar.Text = "despues"; // Patron Reintento var reintentos = 3; var tiempoEspera = 500; //for (int i = 0; i < reintentos; i++) //{ // try // { // // operacion // break; // } // catch (Exception ex) // { // // loggear la excepcion // await Task.Delay(tiempoEspera); // } //} //await Reintentar(ProcesarSaludo); //// Patron de reintento *** //try //{ // var contenido = await Reintentar(async () => // { // using (var respuesta = await httpClient.GetAsync($"{apiURL}/saludos2/edison")) // { // respuesta.EnsureSuccessStatusCode(); // return await respuesta.Content.ReadAsStringAsync(); // } // }); // Console.WriteLine(contenido); //} //catch (Exception ex) //{ // Console.WriteLine("Excepcion atrapada"); //} //// End Patron de reintento *** // Patron solo una tarea // solo quiero que se ejecute una tarea y canccelar las demas //1. //cancellationTokenSource = new CancellationTokenSource(); //var token = cancellationTokenSource.Token; //var nombres = new string[] { "Felipe", "Claudia", "Antonio", "Edison" }; //var tareasHTTP = nombres.Select(x => ObtenerSaludo3(x, token)); //var tarea = await Task.WhenAny(tareasHTTP); //var contenido = await tarea; //Console.WriteLine(contenido.ToUpper()); //cancellationTokenSource.Cancel(); //2. //var tareasHTTP = nombres.Select(x => //{ // Func<CancellationToken, Task<string>> funcion = (ct) => ObtenerSaludo3(x, ct); // return funcion; //}); //var contenido = await EjecutarUno(tareasHTTP); //Console.WriteLine(contenido.ToUpper()); //3. //var contenido = await EjecutarUno( // (ct) => ObtenerSaludo3("Edison", ct), // (ct) => ObtenerAdios("Edison", ct) // ); //Console.WriteLine(contenido.ToUpper()); // End Patron solo una tarea //// Controlar el resultado de la tarea con TaskCompletionSource //var tarea = EvaluarValor(txtInput.Text); //Console.WriteLine("Inicio"); //Console.WriteLine($"Is completed: {tarea.IsCompleted}"); //Console.WriteLine($"Is canceled: {tarea.IsCanceled}"); //Console.WriteLine($"Is faulted: {tarea.IsFaulted}"); //try //{ // await tarea; //} //catch (Exception ex) //{ // Console.WriteLine($"Excepcion: {ex.Message}"); //} //Console.WriteLine("fin"); //Console.WriteLine(""); //// Cancelando tareas no cancelables (metodos asincronos que no reciben un token de cancelacion por ello no se puede usar el cancelationtoken) //// util cuando no se quiere programar un timeout, sino que queremos una tarea que no hace nada pero queremos poderla cancelar //cancellationTokenSource = new CancellationTokenSource(); //try //{ // var resultado = await Task.Run(async () => // { // await Task.Delay(5000); // return 7; // }).WithCancellation(cancellationTokenSource.Token); // Console.WriteLine(resultado); //} //catch (Exception ex) //{ // Console.WriteLine(ex.Message); //} //finally { // cancellationTokenSource.Dispose(); //} // ValueTask //la mision de ValueTask es de performance //escenarios de alta demanda //ValueTask es un struct (tipo valor) //usar cuando: // lo mas probable del resultado de la operacion sea sincrono // cuando la operacion se invoke muy frecuente que el costo de usar task o task<t> sea importante // uso de IEnumerable // iteraciones sobre un tipo (por ejemplo de la lista) //var nombres = new List<string>() { "Edison", "Andrea"}; //foreach (var nombre in nombres) //{ // Console.WriteLine(nombre); //} // yield: para que la lista se entregue de uno en uno // permite generar de uno en uno los valores de un iterable // Stream asyncronos, para poder iterar el tipo task //await foreach (var nombre in GenerarNombres()) //{ // Console.WriteLine(nombre); //} // tres formas de cancelar stream asyncrono //cancellationTokenSource = new CancellationTokenSource(); //try //{ // await foreach (var nombre in GenerarNombres(cancellationTokenSource.Token)) // { // Console.WriteLine(nombre); // } //} //catch (TaskCanceledException ex) //{ // Console.WriteLine("Operacion cancelada"); //} //finally { // cancellationTokenSource?.Dispose(); //} //var nombresEnumerable = GenerarNombres(); //await ProcesarNombres(nombresEnumerable); //Console.WriteLine("fin"); //cancellationTokenSource = null; //Sincrono dentro de Asincrono //var valor = ObtenerValor().Result; //Console.WriteLine(valor //Evitar uso de Task.Factory.StartNew //var resultadoStartNew = await Task.Factory.StartNew(async () => { // await Task.Delay(1000); // return 7; //}).Unwrap(); //var resultadoRun = await Task.Run(async () => //{ // await Task.Delay(1000); // return 7; //}); //Console.WriteLine($"Resultado StartNew: {resultadoStartNew}"); //Console.WriteLine($"----"); //Console.WriteLine($"Resultado Run: {resultadoRun}"); ////PARALELISMO WhenAll //var directorioActual = AppDomain.CurrentDomain.BaseDirectory; //var destinoBaseSecuencial = Path.Combine(directorioActual, @"Imagenes\resultado-secuencial"); //var destinoBaseParalelo = Path.Combine(directorioActual, @"Imagenes\resultado-paralelo"); //PrepararEjecucion(destinoBaseParalelo, destinoBaseSecuencial); //Console.WriteLine("inicio "); //var imagenes = ObtenerImagenes(); //// parte secuencial //var stopwatch = new Stopwatch(); //stopwatch.Start(); //foreach (var imagen in imagenes) //{ // await ProcesarImagen(destinoBaseSecuencial, imagen); //} //var tiempoSecuencial = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duracion en segundos: {0}", tiempoSecuencial); //stopwatch.Restart(); //// parte paralelo //var tareasEnumerable = imagenes.Select(async imagen => await ProcesarImagen(destinoBaseParalelo, imagen)); //await Task.WhenAll(tareasEnumerable); //var tiempoParalelo = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duracion en segundos: {0}", tiempoParalelo); //EscribirComparacion(tiempoSecuencial, tiempoParalelo); //Console.WriteLine("fin"); //PARALELISMO Parallel.For //Console.WriteLine("Secuencial "); //for (int i = 0; i < 11; i++) //{ // Console.WriteLine(i); //} //Console.WriteLine("Paralelo "); //Parallel.For(0, 11, i => Console.WriteLine(i)); //PARALELISMO Velocidad multiplicacion de matrices Parallel.For //var columnasMatrizA = 1100; //var filas = 1000; //var columnasMatrizB = 1750; //var matrizA = Matrices.InicializarMatriz(filas, columnasMatrizA); //var matrizB = Matrices.InicializarMatriz(columnasMatrizA, columnasMatrizB); //var resultado = new double[filas, columnasMatrizB]; //var stopwathc = new Stopwatch(); //stopwathc.Start(); //await Task.Run(() => Matrices.MultiplicarMatricesSecuencial(matrizA, matrizB, resultado)); //var tiempoSecuencial = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duración en segundos: {0}", tiempoSecuencial); //resultado = new double[filas, columnasMatrizB]; //stopwathc.Restart(); //await Task.Run(() => Matrices.MultiplicarMatricesParalelo(matrizA, matrizB, resultado)); //var tiempoParalelo = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duración en segundos: {0}", tiempoParalelo); //EscribirComparacion(tiempoSecuencial, tiempoParalelo); //Console.WriteLine("fin"); //PARALLEL.Foreach //var directorioActual = AppDomain.CurrentDomain.BaseDirectory; //var carpetaOrigen = Path.Combine(directorioActual, @"Imagenes\resultado-secuencial"); //var carpetaDestinoSecuencial = Path.Combine(directorioActual, @"Imagenes\foreach-secuencial"); //var carpetaDestinoParalelo = Path.Combine(directorioActual, @"Imagenes\foreach-paralelo"); //PrepararEjecucion(carpetaDestinoSecuencial, carpetaDestinoParalelo); //var archivos = Directory.EnumerateFiles(carpetaOrigen); //var stopwathc = new Stopwatch(); //stopwathc.Start(); ////Secuencial //foreach (var archivo in archivos) //{ // VoltearImagen(archivo, carpetaDestinoSecuencial); //} //var tiempoSecuencial = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duración en segundos: {0}", tiempoSecuencial); //stopwathc.Restart(); ////Paralelo //Parallel.ForEach(archivos, archivo => { // VoltearImagen(archivo, carpetaDestinoParalelo); //}); //var tiempoParalelo = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duración en segundos: {0}", tiempoParalelo); //EscribirComparacion(tiempoSecuencial, tiempoParalelo); //Console.WriteLine("fin"); // PARALEL.INVOKE // Preparando código de voltear imágenes //var directorioActual = AppDomain.CurrentDomain.BaseDirectory; //var carpetaOrigen = Path.Combine(directorioActual, @"Imagenes\resultado-secuencial"); //var carpetaDestinoSecuencial = Path.Combine(directorioActual, @"Imagenes\foreach-secuencial"); //var carpetaDestinoParalelo = Path.Combine(directorioActual, @"Imagenes\foreach-paralelo"); //PrepararEjecucion(carpetaDestinoSecuencial, carpetaDestinoParalelo); //var archivos = Directory.EnumerateFiles(carpetaOrigen); //// Preparando código de matrices //int columnasMatrizA = 208; //int filas = 1240; //int columnasMatrizB = 750; //var matrizA = Matrices.InicializarMatriz(filas, columnasMatrizA); //var matrizB = Matrices.InicializarMatriz(columnasMatrizA, columnasMatrizB); //var resultado = new double[filas, columnasMatrizB]; //Action multiplicarMatrices = () => Matrices.MultiplicarMatricesSecuencial(matrizA, matrizB, resultado); //Action voltearImagenes = () => //{ // foreach (var archivo in archivos) // { // VoltearImagen(archivo, carpetaDestinoSecuencial); // } //}; //Action[] acciones = new Action[] { multiplicarMatrices, voltearImagenes }; //var stopwatch = new Stopwatch(); //stopwatch.Start(); //// TODO: Algoritmo secuencial //foreach (var accion in acciones) //{ // accion(); //} //var tiempoSecuencial = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duración en segundos: {0}", // tiempoSecuencial); //PrepararEjecucion(carpetaDestinoSecuencial, carpetaDestinoParalelo); //stopwatch.Restart(); //// TODO: Algoritmo paralelo //Parallel.Invoke(acciones); //var tiempoEnParalelo = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duración en segundos: {0}", // tiempoEnParalelo); //EscribirComparacion(tiempoSecuencial, tiempoEnParalelo); //Console.WriteLine("fin"); /// TOKEN PARA CANCELAR //var columnasMatrizA = 1100; //var filas = 1000; //var columnasMatrizB = 1750; //var matrizA = Matrices.InicializarMatriz(filas, columnasMatrizA); //var matrizB = Matrices.InicializarMatriz(columnasMatrizA, columnasMatrizB); //var resultado = new double[filas, columnasMatrizB]; //var stopwathc = new Stopwatch(); //stopwathc.Start(); //await Task.Run(() => Matrices.MultiplicarMatricesSecuencial(matrizA, matrizB, resultado)); //var tiempoSecuencial = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duración en segundos: {0}", tiempoSecuencial); //resultado = new double[filas, columnasMatrizB]; //stopwathc.Restart(); //cancellationTokenSource = new CancellationTokenSource(); //try //{ // await Task.Run(() => Matrices.MultiplicarMatricesParalelo(matrizA, matrizB, resultado, cancellationTokenSource.Token)); //} //catch (Exception) //{ // Console.WriteLine("Operacion cancelada"); //} //finally //{ // cancellationTokenSource.Dispose(); //} //cancellationTokenSource = null; //var tiempoParalelo = stopwathc.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duración en segundos: {0}", tiempoParalelo); //EscribirComparacion(tiempoSecuencial, tiempoParalelo); //Console.WriteLine("fin"); // MAXIMO GRADO DE PARALELISMO //cancellationTokenSource = new CancellationTokenSource(); //for (int i = 1; i < 13; i++) //{ // await RealizarPruebaMatrices(i); //} //Race conditions //Interlock //var valorSinInterlocked = 0; //Parallel.For(0, 1000000, numero => valorSinInterlocked++); //Console.WriteLine($"Sumatoria sin interlocked: {valorSinInterlocked}"); //var valorConInterlocked = 0; //Parallel.For(0, 1000000, numero => Interlocked.Increment(ref valorConInterlocked)); //Console.WriteLine($"Sumatoria sin interlocked: {valorConInterlocked}"); // Locks //var valorIncrementado = 0; //var valorSumado = 0; //var mutex = new object(); //Parallel.For(0, 10000, numero => { // //Interlocked.Increment(ref valorIncrementado); // //Interlocked.Add(ref valorSumado, valorIncrementado); // lock (mutex) // { // valorIncrementado++; // valorSumado += valorIncrementado; // } //}); //Console.WriteLine("---"); //Console.WriteLine($"Valor incrementado: {valorIncrementado}"); //Console.WriteLine($"Valor sumado: {valorSumado}"); // PLINQ //cancellationTokenSource = new CancellationTokenSource(); //var fuente = Enumerable.Range(1, 20); //var elementosPAres = fuente // .AsParallel() // .WithDegreeOfParallelism(2) // .WithCancellation(cancellationTokenSource.Token) // .AsOrdered() // .Where(x => x % 2 == 0).ToList(); //foreach (var numero in elementosPAres) //{ // Console.WriteLine(numero); //} // PLINQ Operaciones de agregado //var fuente = Enumerable.Range(1, 1000); //var suma = fuente.AsParallel().Sum(); //var promedio = fuente.AsParallel().Average(); //Console.WriteLine($"La suma es: {suma}" ); //Console.WriteLine($"El promedio es: {promedio}"); //var matrices = Enumerable.Range(1, 500).Select(x => Matrices.InicializarMatriz(1000, 1000)).ToList(); //Console.WriteLine("matrices generadas"); //var stopwatch = new Stopwatch(); //stopwatch.Start(); //var sumaMatricesSecuencial = matrices.Aggregate(Matrices.SumarMatricesSecuencial); //var tiempoSecuencial = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Secuencial - duración en segundos: {0}", // tiempoSecuencial); //stopwatch.Restart(); //var sumaMatricesParalelo = matrices.AsParallel().Aggregate(Matrices.SumarMatricesSecuencial); //var tiempoEnParalelo = stopwatch.ElapsedMilliseconds / 1000.0; //Console.WriteLine("Paralelo - duración en segundos: {0}", // tiempoEnParalelo); //EscribirComparacion(tiempoSecuencial, tiempoEnParalelo); //----------------- //Parallel.ForAll var queryParalelo = Enumerable.Range(1, 10).AsParallel() .WithDegreeOfParallelism(2).Select(x => Matrices.InicializarMatriz(100, 100)); // Procesa todo junto //foreach (var matriz in queryParalelo) //{ // Console.WriteLine(matriz[0, 0]); //} queryParalelo.ForAll(matriz => Console.WriteLine(matriz[0, 0])); return; //cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(30)); loadingGif.Visible = true; pgProcesamiento.Visible = true; var reportarProgreso = new Progress <int>(ReportarProgresoTarjetas); var stopwatch = new Stopwatch(); stopwatch.Start(); try { var tarjetas = await ObtenerTarjetasDeCredito(20, cancellationTokenSource.Token); await ProcesarTarjetas(tarjetas, reportarProgreso, cancellationTokenSource.Token); } catch (HttpRequestException ex) { MessageBox.Show(ex.Message); } catch (TaskCanceledException ex) { MessageBox.Show("La operacion ha sido cancelada"); } MessageBox.Show($"Operación finalizada en {stopwatch.ElapsedMilliseconds / 1000.0} segundos"); loadingGif.Visible = false; pgProcesamiento.Visible = false; pgProcesamiento.Value = 0; // ... }