Este artículo se tradujo automáticamente. Para ver el artículo en inglés, active la casilla Inglés. Además, puede mostrar el texto en inglés en una ventana emergente si mueve el puntero del mouse sobre el texto.
Traducción
Inglés

Método Task.Run<TResult>(Func<TResult>, CancellationToken)

.NET Framework (current version)
 

Publicado: octubre de 2016

Pone en cola el trabajo especificado para ejecutarlo en el grupo de subprocesos y devuelve un objeto Task(TResult) que representa ese trabajo. Un token de cancelación permite cancelar el trabajo.

Espacio de nombres:   System.Threading.Tasks
Ensamblado:  mscorlib (en mscorlib.dll)

public static Task<TResult> Run<TResult>(
	Func<TResult> function,
	CancellationToken cancellationToken
)

Parámetros

function
Type: System.Func<TResult>

Trabajo que se va a ejecutar de forma asincrónica.

cancellationToken
Type: System.Threading.CancellationToken

Token de cancelación que se debe usar para cancelar el trabajo.

Valor devuelto

Type: System.Threading.Tasks.Task<TResult>

Task(TResult) que representa el trabajo en cola que se va a ejecutar en el grupo de subprocesos.

Parámetros de tipo

TResult

Tipo de resultado de la tarea.

Exception Condition
ArgumentNullException

El parámetro function es null.

TaskCanceledException

La tarea se canceló.

ObjectDisposedException

Se eliminó el CancellationTokenSource asociado a cancellationToken.

Si se solicita la cancelación antes de que comience la tarea de ejecución, la tarea no se ejecuta. En su lugar se establece en el Canceled estado e inicia un TaskCanceledException excepción.

El Run<TResult> método es una alternativa más sencilla a la StartNew (método). Crea una tarea con los valores predeterminados siguientes:

Para obtener información sobre cómo controlar las excepciones producidas por operaciones de la tarea, consulte Control de excepciones (Task Parallel Library).

En el ejemplo siguiente se crea 20 tareas que se reproducción hasta que se incrementa un contador en un valor de 2 millones. Cuando las 10 primeras tareas llegar a millones de 2, el token de cancelación se cancela y se cancelan todas las tareas cuyos contadores no hayan alcanzado 2 millones. El ejemplo muestra el resultado posible.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var tasks = new List<Task<int>>();
      var source = new CancellationTokenSource();
      var token = source.Token;
      int completedIterations = 0;

      for (int n = 0; n <= 19; n++)
         tasks.Add(Task.Run( () => { int iterations = 0;
                                     for (int ctr = 1; ctr <= 2000000; ctr++) {
                                         token.ThrowIfCancellationRequested();
                                         iterations++;
                                     }
                                     Interlocked.Increment(ref completedIterations);
                                     if (completedIterations >= 10)
                                        source.Cancel();
                                     return iterations; }, token));

      Console.WriteLine("Waiting for the first 10 tasks to complete...\n");
      try  {
         Task.WaitAll(tasks.ToArray());
      }
      catch (AggregateException) {
         Console.WriteLine("Status of tasks:\n");
         Console.WriteLine("{0,10} {1,20} {2,14:N0}", "Task Id",
                           "Status", "Iterations");
         foreach (var t in tasks)
            Console.WriteLine("{0,10} {1,20} {2,14}",
                              t.Id, t.Status,
                              t.Status != TaskStatus.Canceled ? t.Result.ToString("N0") : "n/a");
      }
   }
}
// The example displays output like the following:
//    Waiting for the first 10 tasks to complete...
//    Status of tasks:
//
//       Task Id               Status     Iterations
//             1      RanToCompletion      2,000,000
//             2      RanToCompletion      2,000,000
//             3      RanToCompletion      2,000,000
//             4      RanToCompletion      2,000,000
//             5      RanToCompletion      2,000,000
//             6      RanToCompletion      2,000,000
//             7      RanToCompletion      2,000,000
//             8      RanToCompletion      2,000,000
//             9      RanToCompletion      2,000,000
//            10             Canceled            n/a
//            11             Canceled            n/a
//            12             Canceled            n/a
//            13             Canceled            n/a
//            14             Canceled            n/a
//            15             Canceled            n/a
//            16      RanToCompletion      2,000,000
//            17             Canceled            n/a
//            18             Canceled            n/a
//            19             Canceled            n/a
//            20             Canceled            n/a

Instead of using the P:System.AggregateException.InnerExceptions property to examine exceptions, the example iterates all tasks to determine which have completed successfully and which have been cancelled. For those that have completed, it displays the value returned by the task.

Dado que la cancelación es cooperativa, cada tarea puede decidir cómo responder a la cancelación. El ejemplo siguiente es parecida a la primera, salvo que, cuando se cancela el token, tareas de devuelven el número de iteraciones haya completado en lugar de producir una excepción.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var tasks = new List<Task<int>>();
      var source = new CancellationTokenSource();
      var token = source.Token;
      int completedIterations = 0;

      for (int n = 0; n <= 19; n++)
         tasks.Add(Task.Run( () => { int iterations = 0;
                                     for (int ctr = 1; ctr <= 2000000; ctr++) {
                                         if (token.IsCancellationRequested)
                                            return iterations;
                                         iterations++;
                                     }
                                     Interlocked.Increment(ref completedIterations);
                                     if (completedIterations >= 10)
                                        source.Cancel();
                                     return iterations; }, token));

      Console.WriteLine("Waiting for the first 10 tasks to complete...\n");
      try  {
         Task.WaitAll(tasks.ToArray());
      }
      catch (AggregateException) {
         Console.WriteLine("Status of tasks:\n");
         Console.WriteLine("{0,10} {1,20} {2,14:N0}", "Task Id",
                           "Status", "Iterations");
         foreach (var t in tasks)
            Console.WriteLine("{0,10} {1,20} {2,14}",
                              t.Id, t.Status,
                              t.Status != TaskStatus.Canceled ? t.Result.ToString("N0") : "n/a");
      }
   }
}
// The example displays output like the following:
//    Status of tasks:
//
//       Task Id               Status     Iterations
//             1      RanToCompletion      2,000,000
//             2      RanToCompletion      2,000,000
//             3      RanToCompletion      2,000,000
//             4      RanToCompletion      2,000,000
//             5      RanToCompletion      2,000,000
//             6      RanToCompletion      2,000,000
//             7      RanToCompletion      2,000,000
//             8      RanToCompletion      2,000,000
//             9      RanToCompletion      2,000,000
//            10      RanToCompletion      1,658,326
//            11      RanToCompletion      1,988,506
//            12      RanToCompletion      2,000,000
//            13      RanToCompletion      1,942,246
//            14      RanToCompletion        950,108
//            15      RanToCompletion      1,837,832
//            16      RanToCompletion      1,687,182
//            17      RanToCompletion        194,548
//            18             Canceled    Not Started
//            19             Canceled    Not Started
//            20             Canceled    Not Started

The example still must handle the T:System.AggregateException exception, since any tasks that have not started when cancellation is requested still throw an exception.

Plataforma universal de Windows
Disponible desde 8
.NET Framework
Disponible desde 4.5
Biblioteca de clases portable
Se admite en: plataformas portátiles de .NET
Windows Phone Silverlight
Disponible desde 8.0
Windows Phone
Disponible desde 8.1
Volver al principio
Mostrar: