Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

573
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!