Gibt es eine Klasse im .NET -Framework, um einen Haltecontainer für Objekte darzustellen?

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

  •  04-10-2019
  •  | 
  •  

Frage

Ich suche eine Klasse, die eine Haltestruktur für ein Objekt definiert. Der Wert für dieses Objekt könnte zu einem späteren Zeitpunkt festgelegt werden, als wenn dieser Container erstellt wird. Es ist nützlich, eine solche Struktur in Lambdas oder in Rückruffunktionen usw. zu bestehen usw.

Sagen:

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());

Es ist ziemlich einfach, diese Struktur zu definieren, aber ich versuche zu sehen, ob man in FCL erhältlich ist. Ich möchte auch, dass dies eine effiziente Struktur ist, die alle Funktionen wie Gewindesicherheit, effizientes Warten usw. benötigt.

Jede Hilfe wird sehr geschätzt.

War es hilfreich?

Lösung

Ich habe noch nie eine solche Klasse gesehen, sollte aber ziemlich einfach sein.

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

Andere Tipps

Was Sie versuchen zu erreichen, fühlt sich einer Zukunft sehr ähnlich. Frühe CTPs von .NET 4.0 TPL hatten a Future<T> Klasse. Mit dem RTM von .NET 4.0 wurde es umbenannt Task<T>. Wenn Sie schicken, können Sie die Ähnlichkeit zwischen:

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

und

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

Wenn Sie .NET 4.0 noch nicht verwenden, können Sie die herunterladen Reaktive Erweiterungen für .NET 3.5SP1. Es enthält ein System.Threading.dll -Assembly, das TPL für .NET 3.5 enthält.


Während Value ist nur schreibgeschützt, wenn Sie dies ändern, kann dies natürlich durch den Rückgabewert des Delegiertens erfolgen, den Sie für die Aufgabe liefern. Natürlich bin ich mir nicht ganz sicher, ob dies Ihren Anforderungen entspricht, aber Ihr Beispiel kann wie folgt geschrieben werden:

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

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

var bytes = downloadBytesTask.Value;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top