Question

Pour une raison quelconque, le QueueWorkItem de de ThreadPool ne renvoie pas de IAsyncResult ou un autre descripteur de l'élément de travail, ce qui permettrait attendre que ce soit terminé. Il existe des méthodes RegisterWait ... , mais vous devez passer un WaitHandle et leur création coûte cher (voir la documentation IAsyncResult , qui vous conseille de retarder la création d'un WaitHandle jusqu'à ce que demandé). La bibliothèque parallèle de tâches corrigera ce manque, mais il faut attendre longtemps avant que cela soit disponible. Alors, y at-il des problèmes avec cette conception:

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: J'ai posé une question de suivi sur les préoccupations qui surviennent lors de l’utilisation de délégués asynchrones au lieu du ThreadPool .

Était-ce utile?

La solution

Eh bien, vous avez une condition de concurrence entre aller chercher WaitHandle et le régler. Voulez-vous vraiment que l'appelant attende pour toujours s'il lui arrive d'être un peu en retard?

Vous devriez probablement effectuer un verrouillage approprié et conserver un " j'ai terminé " Indiquez que si vous créez le WaitHandle une fois terminé, vous le définissez avant de le renvoyer.

J'écrirais aussi personnellement une méthode fabrique statique plutôt que d'utiliser simplement un constructeur public - ou en ferais un "créer et puis , démarrer explicitement" et modèle. Mettre en file d'attente l'élément de travail dans le constructeur me semble bizarre.

Autres conseils

Pourquoi n'utilisez-vous pas un délégué asynchrone, comme présenté ici:

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

Cela rendrait Concurrent obsolète, non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top