Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

580
Vistas
¿En qué programador se ejecuta Task.ContinueWith()?

Considere el siguiente código:

 // MyKickAssTaskScheduler is a TaskScheduler, IDisposable using (var scheduler = new MyKickAssTaskScheduler()) { Task foo = new Task(() => DoSomething()); foo.ContinueWith((_) => DoSomethingElse()); foo.Start(scheduler); foo.Wait(); }

¿Está garantizada la ejecución de la tarea ContinueWith() en mi programador? Si no, ¿qué programador usará?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

StartNew, ContinueWith será predeterminado a TaskScheduler.Current, Current devolverá el programador predeterminado, cuando no se llame desde dentro de una tarea (MSDN).

Para evitar el problema del programador predeterminado, siempre debe pasar un TaskScheduler explícito a Task.ContinueWith y Task.Factory.StartNew.

Continuar con es peligroso

over 4 years ago · Santiago Trujillo Denunciar

0

¿Está garantizada la ejecución de la tarea ContinueWith() en mi programador? Si no, ¿qué programador usará?

No, utilizará el programador pasado a la Task original. ContinueWith usará de forma predeterminada TaskScheduler.Current , en cuyo caso es el programador de tareas del grupo de subprocesos predeterminado. No hay propagación entre su contexto proporcionado a task.Start y el que se usa dentro de la continuación

De la fuente :

 public Task ContinueWith(Action<Task> continuationAction) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return ContinueWith(continuationAction, TaskScheduler.Current, default(CancellationToken), TaskContinuationOptions.None, ref stackMark); }
over 4 years ago · Santiago Trujillo Denunciar

0

@Noseratio: léalo, pero aún escéptico sobre la validez de este comportamiento: ejecuté la primera tarea en un programador no predeterminado por una razón. ¿Por qué TPL decidió que la continuación, que siempre es secuencial a mi tarea, debería ejecutarse en otra?

Estoy de acuerdo, este no es el mejor diseño, pero me imagino que el valor predeterminado de TaskScheduler.Current está ahí para que ContinueWith sea coherente con Task.Factory.StartNew , que también tiene como valor predeterminado TaskScheduler.Current , en primer lugar. Stephen Toub explica la última decisión de diseño:

En muchas situaciones, ese es el comportamiento correcto. Por ejemplo, supongamos que está implementando un problema recursivo de divide y vencerás, en el que tienes una tarea que se supone que debe procesar una parte del trabajo y, a su vez, subdivide su trabajo y programa tareas para procesar esas partes. Si esa tarea se estaba ejecutando en un programador que representaba un conjunto particular de subprocesos, o si se estaba ejecutando en un programador que tenía un límite de simultaneidad, etc., normalmente desearía que las tareas que creó también se ejecutaran en el mismo programador. .

Por lo tanto, ContinueWith usa el TaskScheduler.Current actual (ambiente) de cualquier tarea que se esté ejecutando actualmente en el momento en que llama a ContinueWith , en lugar de la de la tarea antecedente. En caso de que esto sea un problema para usted y no pueda especificar explícitamente el programador de tareas, existe una solución alternativa. Puede hacer que su programador de tareas personalizado sea el ambiental para un ámbito particular, como este:

 using (var scheduler = new MyKickAssTaskScheduler()) { Task<Task> outer = new Task(() => { Task foo = new Task(() => DoSomething()); foo.ContinueWith((_) => DoSomethingElse()); foo.Start(); // don't have to specify scheduler here return foo; } outer.RunSynchronously(scheduler); outer.Unwrap().Wait(); }

Tenga en cuenta que outer es Task<Task> , por lo tanto, hay outer.Unwrap() . También podrías hacer outer.Result.Wait() , pero hay alguna diferencia semántica, especialmente si outer.Start(scheduler) en lugar de outer.RunSynchronously(scheduler) .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda