Pregunta

La forma idiomáticas para iniciar un nuevo efecto secundario de sólo tarea (es decir: una tarea que no devuelve ningún resultado) mediante el TPL en .NET 4.0 está utilizando la siguiente API:

Task Task.Factory.StartNew(Action<object>, object)   

Pero ¿por qué no la firma de esta API este aspecto

Task Task.Factory.StartNew<T>(Action<T>, T) 

o como esto

Task Task.Factory.StartNew<T>(T, Action<T>) 

Las razones técnicas o alguna otra razón?

¿Fue útil?

Solución

Bien, ahora que entiendo la pregunta correctamente:)

Creo que es porque esto está destinado a ser un directa reemplazo para ThreadPool.QueueUserWorkItem . Me acuerdo que parece un poco extraño ... pero si que está utilizando expresiones lambda de todos modos, es probable que sea más fácil de usar la versión que hace tomar un parámetro de estado (es decir, Action en lugar de Action<object>) y acaba de capturar el valor que le interesa de antemano. No sirve de nada si está especificando el valor y la función por separado: (

Otros consejos

De acuerdo con un mensaje por Stephen Toub (MSFT), que están asumiendo que vamos a depender de cierres para pasar los datos de estado. También hubo alguna excusa de la firma ambigüedad. ( http: //social.msdn. microsoft.com/Forums/en/parallelextensions/thread/1988294c-de41-476a-a104-aa550b7409f5 )

Sin embargo, basándose en los cierres de resolver este problema parece ser un corte temporal a la espera de una solución mejor. Funciona, pero no es una buena solución a más largo plazo. Hay muchas veces que simplemente especificando un método delegado como la acción sería el enfoque más simple, pero eso significa que tenemos que utilizar VARs globales o que están excluidos de la transmisión de parámetros de estado.

Me gusta una de las propuestas de Hugo (de la fijación del foro MS). Hugo sugirió la introducción de un tipo TaskState, lo que parece ser una manera inteligente para eludir el problema de los genéricos ambigüedad.

Aplicando esto a la Task.Factory.StartNew () La firma y el Grupo () constructor como tal:

  public Task<T>( Action<T> function, TaskState<T> state );
  public Task<T,TResult>( Func<T,TResult> function, TaskState<T> state );

ActionState sería muy parecido a la clase anulable - sólo un simple envoltura alrededor de un miembro de Valor. En la práctica, el uso de TaskState podría tener este aspecto:

  var myTask = new Task( MyMethod, new TaskState( stateInfo ) );
  ...

  public void MyMethod( StateInfo stateInfo ) { ... }

El TaskState <> solución no es perfecta, pero parece una solución mucho mejor que depender de cierre de la conversión de tipos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top