首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AsyncLazy的处置,正确的方式是什么(使用方便,不漏)?

AsyncLazy的处置,正确的方式是什么(使用方便,不漏)?
EN

Stack Overflow用户
提问于 2014-07-04 16:27:24
回答 2查看 1.4K关注 0票数 7

我使用的是专门化的Stephen的AsyncLazy实现,来自他的博客。

代码语言:javascript
运行
复制
/// <summary>
/// Provides support for asynchronous lazy initialization.
/// This type is fully thread-safe.
/// </summary>
/// <typeparam name="T">
/// The type of object that is being asynchronously initialized.
/// </typeparam>
public sealed class AsyncLazy<T>
{
    /// <summary>
    /// The underlying lazy task.
    /// </summary>
    private readonly Lazy<Task<T>> instance;

    /// <summary>
    /// Initializes a new instance of the 
    /// <see cref="AsyncLazy&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="factory">
    /// The delegate that is invoked on a background thread to produce
    /// the value when it is needed.
    /// </param>
    /// <param name="start">
    /// If <c>true</c> commence initialization immediately.
    /// </param>
    public AsyncLazy(Func<T> factory, bool start = false)
    {
        this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
        if (start)
        {
            this.Start();
        }
    }

    /// <summary>
    /// Initializes a new instance of the 
    /// <see cref="AsyncLazy&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="factory">
    /// The asynchronous delegate that is invoked on a background 
    /// thread to produce the value when it is needed.
    /// </param>
    /// <param name="start">
    /// If <c>true</c> commence initialization immediately.
    /// </param>
    public AsyncLazy(Func<Task<T>> factory, bool start = false)
    {
        this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
        if (start)
        {
            this.Start();
        }
    }

    /// <summary>
    /// Asynchronous infrastructure support.
    /// This method permits instances of
    /// <see cref="AsyncLazy&lt;T&gt;"/> to be await'ed.
    /// </summary>
    public TaskAwaiter<T> GetAwaiter()
    {
        return this.instance.Value.GetAwaiter();
    }

    /// <summary>
    ///     Starts the asynchronous initialization, 
    ///     if it has not already started.
    /// </summary>
    public void Start()
    {
        var unused = this.instance.Value;
    }
}

这是一个很好的代码,我真的很欣赏它的易用性。即

代码语言:javascript
运行
复制
class SomeClass
{
    private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
        () => new Thing());

    void SomeMethod()
    {
        var thing = await theThing;
        // ...
    }
}

,现在我的问题,

假设SomeClass继承了实现IDisposable的类,而Thing则实现了IDisposable。我们会有这样的框架实现,

代码语言:javascript
运行
复制
class SomeClass : SomeDisposableBase
{
    private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
        () => new Thing());

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // What do I do with theThing?
        }

        base.Dispose(disposing);
    }
}

那么,如何处理theThingDispose覆盖中的操作呢?我应该扩展AsyncLazy<T>以拥有一个新的属性吗?

代码语言:javascript
运行
复制
// ...

public bool IsStarted
{
    get
    {
        return this.instance.IsValueCreated;
    }
}

// ...

我是否应该更改AsyncLazy<T>以实现IDisposable

我是不是误解了,我不需要担心?

我该做点别的吗?

EN

Stack Overflow用户

发布于 2014-07-04 16:54:25

斯蒂芬·图布对这门课的看法是从Lazy<Task<T>>继承的,因此您可以自动获得IsValueCreated属性。

或者,您可以从私有字段公开IsValueCreated属性:

代码语言:javascript
运行
复制
public sealed class AsyncLazy<T>
{
    private readonly Lazy<Task<T>> instance;
    ...
    public bool IsValueCreated
    {
        get { return instance.IsValueCreated; }
    }
}

为了与内置Lazy<T>类型保持一致,我避免将属性重命名为IsStarted

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24578185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档