Pregunta

Por cualquier razón, ThreadPool ' QueueWorkItem no devuelve un IAsyncResult o algún otro identificador al elemento de trabajo, lo que permitiría esperar hasta que se complete. Existen métodos RegisterWait ... , pero debe pasar un WaitHandle y crearlos es costoso (consulte la documentación de IAsyncResult , que le aconseja que retrasar la creación de un WaitHandle hasta que se solicite). La biblioteca paralela de tareas solucionará esta falta, pero hay que esperar mucho antes de que esté disponible. Entonces, ¿hay algún problema con este diseño?

public class Concurrent<T> {
    private ManualResetEvent _resetEvent;
    private T _result;

    public Concurrent(Func<T> f) {
        ThreadPool.QueueUserWorkItem(_ => {
                                         _result = f();
                                         if (_resetEvent != null)
                                             _resetEvent.Set();
                                     });
    }

    public WaitHandle WaitHandle {
        get {
            if (_resetEvent == null)
                _resetEvent = new ManualResetEvent(_result != null);
            return _resetEvent;
        }

    ...

EDITAR: Hice una pregunta de seguimiento sobre las inquietudes que surgen cuando se usan delegados asíncronos en lugar de ThreadPool .

¿Fue útil?

Solución

Bueno, tienes una condición de carrera entre buscar el WaitHandle y configurarlo. ¿Realmente quieres que la persona que llama esté esperando para siempre si llega un poco tarde?

Probablemente debería hacer un bloqueo apropiado y mantener un " he terminado " indicador de modo que si lo hace crea WaitHandle después de que haya finalizado, configúrelo antes de devolverlo.

También escribiría personalmente un método de fábrica estático en lugar de solo usar un constructor público, o convertirlo en " crear y luego iniciar explícitamente " modelo. Poner en cola el elemento de trabajo en el constructor me parece extraño.

Otros consejos

¿Por qué no estás usando un delegado asíncrono, como se demuestra aquí:

http://msdn.microsoft.com/en-us/library /h80ttd5f.aspx

Eso volvería obsoleto concurrente, ¿no?

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