Domanda

Per qualsiasi motivo, il ThreadPool QueueWorkItem non restituisce un IAsyncResult o qualche altro handle per l'elemento di lavoro, che consentirebbe attendere fino al completamento. Esistono metodi RegisterWait ... , ma devi passare un WaitHandle e la loro creazione è costosa (vedi la documentazione IAsyncResult , che ti consiglia di ritardare la creazione di un WaitHandle fino a quando richiesto). Task Parallel Library risolverà questa mancanza, ma c'è una lunga attesa prima che sia disponibile. Quindi, ci sono problemi con questo design:

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;
        }

    ...

EDIT: Ho fatto una domanda di follow-up sui dubbi che si presentano quando si utilizzano delegati asincroni anziché ThreadPool .

È stato utile?

Soluzione

Bene, hai una condizione di gara tra il recupero di WaitHandle e l'impostazione. Vuoi davvero che il chiamante stia aspettando per sempre se capita di essere un po 'in ritardo?

Probabilmente dovresti fare un blocco appropriato e mantenere un " Ho finito " in modo che se fai crei WaitHandle al termine, lo imposti prima di restituirlo.

Scriverei anche personalmente un metodo statico di fabbrica piuttosto che semplicemente usando un costruttore pubblico - o lo farei un " creare e quindi avviare esplicitamente " modello. Accodare l'oggetto di lavoro nel costruttore mi sembra strano.

Altri suggerimenti

Perché non stai usando un delegato asincrono, come mostrato qui:

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

Ciò renderebbe Concurrent obsoleto, no?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top