Y a-t-il une classe dans le framework .NET pour représenter un conteneur de maintien pour les objets?

StackOverflow https://stackoverflow.com/questions/2796674

  •  04-10-2019
  •  | 
  •  

Question

Je recherche une classe qui définit une structure de maintien pour un objet. La valeur de cet objet peut être définie ultérieurement que lorsque ce conteneur est créé. Il est utile de passer une telle structure en lambdas ou dans les fonctions de rappel, etc.

Dire:

class HoldObject<T> {
 public T Value { get; set; }
 public bool IsValueSet();
 public void WaitUntilHasValue();
}

// and then we could use it like so ...

HoldObject<byte[]> downloadedBytes = new HoldObject<byte[]>();
DownloadBytes("http://www.stackoverflow.com", sender => downloadedBytes.Value = sender.GetBytes());

Il est assez facile de définir cette structure, mais j'essaie de voir si l'on est disponible en FCL. Je veux aussi que ce soit une structure efficace qui a toutes les fonctionnalités nécessaires comme la sécurité des fils, l'attente efficace, etc.

Toute aide est grandement appréciée.

Était-ce utile?

La solution

Jamais vu une classe comme ça, mais devrait être assez simple.

public class ObjectHolder<T>
{
    private T value;
    private ManualResetEvent waitEvent = new ManualResetEvent(false);

    public T Value
    {
        get { return value; }
        set
        {
            this.value = value;

            ManualResetEvent evt = waitEvent;

            if(evt != null)
            {
                evt.Set();
                evt.Dispose();
                evt = null;
            }
        }
    }

    public bool IsValueSet
    {
        get { return waitEvent == null; }
    }

    public void WaitUntilHasValue()
    {
        ManualResetEvent evt = waitEvent;

        if(evt != null) evt.WaitOne();
    }
}

Autres conseils

Ce que vous essayez d'accomplir ressemble beaucoup à un avenir. Les premiers CTP de .NET 4.0 TPL avaient un Future<T> classer. Avec le RTM de .NET 4.0, il a été renommé Task<T>. Si vous plissez les yeux, vous pouvez voir la ressemblance entre:

class HoldObject<T>
{
    public T Value { get; set; }
    public bool IsValueSet();
    public void WaitUntilHasValue();
}

et

class Task<T>
{
    public T Value { get }
    public bool IsCompleted { get; }
    public void Wait();
}

Si vous n'utilisez pas encore .net 4.0, vous pouvez télécharger le Extensions réactives pour .NET 3.5SP1. Il contient un assemblage System.Threading.dll qui contient TPL pour .net 3.5.


Tandis que le Value est en lecture seule, le changeant peut bien sûr être effectué par la valeur de retour du délégué que vous fournissez la tâche. Bien sûr, je ne sais pas exactement si cela répond à vos besoins, mais votre exemple peut être écrit comme suit:

var downloadBytesTask = Task<byte[]>.Factory.StartNew(() => 
    DownloadBytes("http://www.stackoverflow.com"));

if (!downloadBytesTask.IsCompleted)
{
    downloadBytesTask.Wait();
}

var bytes = downloadBytesTask.Value;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top