using System;
using System.Threading;
using System.Threading.Tasks;
namespace Recetas.Multithreading.R0403
{
public class CombinacionTareas
{
public static void Main()
{
// Creación de dos tareas para ejecutar el método Proceso:
var tareaNo1 = new Task<int>( () => Proceso("Tarea No. 1", 3));
var tareaNo2 = new Task<int>( () => Proceso("Tarea No. 2", 2));
// Una vez terminada la ejecución de `tareaNo1`, se continua con la ejecución
// de la expresión lambda de ContinueWith:
tareaNo1.ContinueWith(
t => Console.WriteLine ("Respuesta Tarea no. 1: {0}. ID Thread: {1}. ¿Thread de pool de threads?: {2}.",
t.Result,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion
);
// Inicia la ejecución asincrónica de los objetos Task:
tareaNo1.Start();
tareaNo2.Start();
// Detiene la ejecución del thread de `Main`
// para dar tiempo de ejecución a los objetos Task:
Thread.Sleep(TimeSpan.FromSeconds(4));
// Creación de tarea de continuación para responder a
// la finalización de de la Tarea no. 2:
Task continuacion = tareaNo2.ContinueWith(
t => Console.WriteLine ("Respuesta Tarea no. 2: {0}. ID Thread: {1}. ¿Thread de pool de threads?: {2}.",
t.Result,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion |
TaskContinuationOptions.ExecuteSynchronously
);
// Se ejecuta una vez que el objeto Task `tareaNo2` finalice:
continuacion.GetAwaiter().OnCompleted(
() => Console.WriteLine ("Tarea de continuación de tarea 2 se completó. ID thread: {0}. ¿Thread de pool de threads?: {1}",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread)
);
// Detiene la ejecución del thread de Main
// para dar tiempo de ejecución a los objetos Task:
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine ();
// Crea otra tarea con dos tareas -una anidad y otra de continuación-:
var tareaNo3 = new Task<int>( () => {
// Crea objeto Task anidado:
var tareaAnidada = Task.Factory.StartNew(() =>
Proceso("Tarea no. 4", 5),
TaskCreationOptions.AttachedToParent
);
// Una vez se complete la tarea anidada continuar con:
tareaAnidada.ContinueWith( t =>
Proceso("Tarea no. 5", 2),
TaskContinuationOptions.AttachedToParent);
return Proceso("Tarea no. 3", 2);
});
// Ejecución Tarea no. 3:
tareaNo3.Start();
// Mientras que la tarea no. 3 se esté ejecutando:
while(!tareaNo3.IsCompleted)
{
// Muestra en la salida estándar el estado actual
// de ejecución del objeto Task `taskNo3`:
Console.WriteLine ("Estado ejecución Tarea no. 3: {0}", tareaNo3.Status);
// Espera por ciclo:
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine ("\nÚltimo estado de Tarea no. 3: {0}.", tareaNo3.Status);
// Espera en thread Main hasta de 10 segundos:
Thread.Sleep(TimeSpan.FromSeconds(10));
Console.WriteLine ();
}
// Proceso asincrónico para objetos Task:
public static int Proceso(string nombre, int segundos)
{
Console.WriteLine ("La {0} se está ejecutando en el ID de thread {1}. ¿Thread del pool de threads?: {2}.",
nombre,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
// Espera simulada para este método de ejecución asincrónica:
Thread.Sleep(TimeSpan.FromSeconds(segundos));
return 45 * segundos;
}
}
}