Todavía estoy aprendiendo toda la Tarea-concepto y TPL. Desde mi comprensión actual, la SynchronizationContext funciones (si está presente) son utilizados por await para el envío de la Tarea «en algún lugar». Por otro lado, las funciones en el Task clase no usar el contexto, ¿verdad?

Así, por ejemplo Task.Run(...) siempre despacho de la acción en un subproceso de trabajo de la rosca de la piscina y de ignorar el SynchronizationContext.Current completamente. await Foobar() sería usar el contexto para ejecutar la tarea generada después de la await?

Si eso es cierto, mi pregunta es: ¿Cómo puedo obtener una Task, que en realidad se ejecuta una acción, sino que se distribuye mediante SynchronizationContext.Current.Send/Post ?

Y ¿alguien puede recomendar una buena introducción en SynchronizationContext, especialmente cuando y cómo son utilizados por el resto del marco? El MSDN parece ser muy tranquilo acerca de la clase. La parte superior de Google hits (aquí y aquí) parecen ser adaptado a Windows Formularios de envío de sólo. Stephen Cleary escribió un artículo lo cual es bueno para aprender qué contextos ya existen y cómo funcionan, pero me falta la comprensión de dónde y cuándo se utilizan realmente.

InformationsquelleAutor Imi | 2013-06-04

2 Comentarios

  1. 39

    ¿Cómo puedo obtener una Tarea, que en realidad se ejecuta una acción, sino que se distribuye mediante
    SynchronizationContext.Actual.Enviar/Post?

    Uso especial programador de tareas:

    Task.Factory.StartNew(
        () => {}, //this will use current synchronization context
        CancellationToken.None, 
        TaskCreationOptions.None, 
        TaskScheduler.FromCurrentSynchronizationContext());

    Y ¿alguien puede recomendar una buena introducción en SynchronizationContext

    Vistazo al artículo Es Todo Acerca de la SynchronizationContext por Stephen Cleary.

    • ah, bueno. gracias. Hay alguna diferencia entre Task.Run y Task.Factory.StartNew ? (Me refiero.. cualquier otra diferencia que la de que «Task.Factory.StartNew aceptar algún parámetro que Task.Run no» ;))
    • Vistazo a este artículo. Gracias por el enlace. Ya he leído ese artículo y enlazado en mi pregunta, muy buena para la comprensión de lo que existen contextos y por qué se han introducido en el primer lugar. Cualquier otro bien de fuentes, tal vez de entrar en detalle acerca de qué clase utiliza los contextos cuando? O hacer que me acerco a la TPL erróneamente y que debo leer acerca de «¿por Qué yo debería en realidad nunca la atención sobre este»? :D.
    • No son algunos otros diferencias entre Task.Run y Task.Factory.StartNew: Task.Run entiende y automáticamente se desenvuelve async delegados, Task.Run siempre utiliza el grupo de subprocesos de programador (mientras Task.Factory.StartNew va a usar el programador de tareas), y Task.Run pasará el DenyChildAttach opción por defecto.
    • Debe haber TaskCreationOptions.None en lugar de TaskContinuationOptions.None?
  2. 26

    Como estás aprendiendo esto, es importante señalar que Task como el usado por el TPL es muy diferente a la de Task como el usado por async/await, a pesar de que sean del mismo tipo. Por ejemplo, TPL utiliza comúnmente para los padres/hijo de tareas, pero async/await no.

    TPL utiliza programadores de tareas para ejecutar sus tareas. Como Dennis señaló, TaskScheduler.FromCurrentSynchronizationContext le dará un programador de tareas que utiliza Post en la actual SynchronizationContext para ejecutar su tarea.

    async/await no suele usar, la tarea de los programadores. Tengo una introductorio async/esperan post en mi blog que incluye información de contexto, y yo también menciona brevemente en mi Artículo de MSDN (es fácil pasar por alto, sin embargo). Básicamente, cuando un async método suspende en un await, por defecto se captura la actual SynchronizationContext (a menos que sea null, en cuyo caso se pondrán a la captura de la corriente de TaskScheduler). Cuando el async método se reanuda, se reanuda la ejecución en ese contexto.

    Dennis señaló el TPL manera de programar una tarea para la actual SynchronizationContext, pero en async/await mundo, que el enfoque no es necesario. En lugar, usted puede explícitamente programar tareas para que el hilo de la piscina a través de Task.Run:

    async Task MyMethodAsync()
    {
      //Whee, on a SynchronizationContext here!
      await Task.Run(() => { }); //Ooo, on the thread pool!
      //Back on the SynchronizationContext ...
      // ... automagically!
    }

    Escribí mi SynchronizationContext artículo precisamente porque el MSDN docs fueron tan carente. Tengo un poco más de información en mi blog, pero todos los bits están en el artículo de MSDN. Muchos tipos de uso de AsyncOperation en lugar de SynchronizationContext directamente; la mejor documentación para esto es enterrado bajo la EAP docs (sección «Threading y el Contexto»). Pero también debo señalar que la EAP es efectivamente obsoleta debido a la async/await, así que no escribir código usando AsyncOperation (o SynchronizationContext) – a menos de que en realidad estaba escribir mi propia SynchronizationContext.

    • SynchronizationContext (a menos que sea nulo, en cuyo caso se pondrán a la captura de la corriente de TaskScheduler). Interesante… en Realidad, al leer en TaskScheduler, me pongo a pensar que un TaskScheduler – no SynchronizationContext – es lo que necesito para mi problema original (no se describe aquí). ¿Tienes buenas referencias de TaskSchedulers vs SynchronizationContexts y lo que la diferencia en realidad es? (A partir de la observación de MSDN, ambos parecen ser los responsables sheduling tareas en los hilos, ¿verdad?)
    • SynchronizationContext fue desarrollado con .NET 2.0 y es usado para la programación de los delegados (de forma sincrónica o asincrónica). TaskScheduler se introdujo en .NET 4.0 y es usado para la programación de tareas (asincrónica).

Dejar respuesta

Please enter your comment!
Please enter your name here