3

オブジェクトの保持構造を定義するクラスを探しています。このオブジェクトの値は、このコンテナが作成されたときよりも後で設定される可能性があります。このような構造体をラムダやコールバック関数などで渡すと便利です。

言う:

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で利用できるかどうかを確認しようとしています。また、これを、スレッドセーフ、効率的な待機など、必要なすべての機能を備えた効率的な構造にしたいと考えています。

どんな助けでも大歓迎です。

4

2 に答える 2

3

そのようなクラスを見たことがありませんが、かなり単純なはずです。

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();
    }
}
于 2010-05-09T05:17:27.687 に答える
3

あなたが達成しようとしていることは、まるで未来のように感じます。.NET 4.0 TPL の初期の CTP にはFuture<T>クラスがありました。.NET 4.0 の RTM では、名前が に変更されました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 をまだ使用していない場合は、Reactive Extensions for .NET 3.5sp1 をダウンロードできます。これには、.NET 3.5 の TPL を含む System.Threading.dll アセンブリが含まれています。


Value読み取り専用ですが、もちろん、タスクに指定したデリゲートの戻り値によって変更できます。もちろん、これが要件を満たしているかどうかは正確にはわかりませんが、例は次のように記述できます。

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

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

var bytes = downloadBytesTask.Value;
于 2010-05-09T09:39:35.623 に答える