Есть ли в .NET Framework какой-либо класс, представляющий контейнер хранения объектов?

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

  •  04-10-2019
  •  | 
  •  

Вопрос

Я ищу класс, который определяет структуру хранения объекта.Значение для этого объекта может быть установлено позже, чем при создании этого контейнера.Полезно передавать такую ​​структуру в лямбды, функции обратного вызова и т. д.

Сказать:

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

Определить эту структуру довольно легко, но я пытаюсь выяснить, доступна ли она в FCL.Я также хочу, чтобы это была эффективная структура со всеми необходимыми функциями, такими как потокобезопасность, эффективное ожидание и т. д.

Любая помощь очень ценится.

Это было полезно?

Решение

Никогда не видел такого класса, но он должен быть довольно простым.

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

Другие советы

То, чего вы пытаетесь достичь, очень похоже на будущее.Ранние версии CTP .NET 4.0 TPL имели Future<T> сорт.В окончательной первоначальной версии .NET 4.0 он был переименован в Task<T>.Если прищуриться, то можно увидеть сходство между:

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

и

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

Если вы еще не используете .NET 4.0, вы можете загрузить Реактивные расширения для .NET 3.5sp1.Он содержит сборку System.Threading.dll, содержащую TPL для .NET 3.5.


В то время Value доступен только для чтения, его изменение, конечно, можно выполнить с помощью возвращаемого значения делегата, который вы предоставляете задаче.Я, конечно, не совсем уверен, соответствует ли это вашим требованиям, но ваш пример можно записать так:

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

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

var bytes = downloadBytesTask.Value;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top