如何在ASP.NET MVC控制器中使用Lazy <T>?

Pur*_*ome 6 .net c# asp.net lazy-loading asp.net-mvc-3

我有一个简单的ASP.NET MVC控制器.在一些操作方法中,我访问了一个我认为很贵的资源.

所以我想,为什么不让它静止.所以我没有做双重检查锁定,而是认为我可以利用Lazy<T>.NET 4.0中的使用.一次而不是多次调用昂贵的服务.

所以,如果这是我的pseduo代码,我怎么能改变它使用Lazy<T>.对于这个懊悔的例子,我将使用File System作为昂贵的资源所以在这个例子中,每次请求调用ActionMethod时,我都希望使用Lazy来保存文件列表,而不是从目标路径获取所有文件. ..当然,这只是第一次打电话.

下一个假设:如果内容发生了变化,请不要担心.这是超出范围的.

public class FooController : Controller
{
    private readonly IFoo _foo;
    public FooController(IFoo foo)
    {
        _foo = foo;
    }

    public ActionResult PewPew()
    {
        // Grab all the files in a folder.
        // nb. _foo.PathToFiles = "/Content/Images/Harro"
        var files = Directory.GetFiles(Server.MapPath(_foo.PathToFiles));

        // Note: No, I wouldn't return all the files but a concerete view model
        //       with only the data from a File object, I require.
        return View(files);
    }
}
Run Code Online (Sandbox Code Playgroud)

Gre*_*reg 5

在您的示例中,结果Directory.GetFiles取决于值_foo,而不是静态值.因此,您不能Lazy<string[]>在控制器的所有实例之间使用静态实例作为共享缓存.

ConcurrentDictionary<TKey, TValue>喜欢的事,更接近你想要的声音.

// Code not tested, blah blah blah...
public class FooController : Controller
{
    private static readonly ConcurrentDictionary<string, string[]> _cache
        = new ConcurrentDictionary<string, string[]>();

    private readonly IFoo _foo;
    public FooController(IFoo foo)
    {
        _foo = foo;
    }

    public ActionResult PewPew()
    {
        var files = _cache.GetOrAdd(Server.MapPath(_foo.PathToFiles), path => {
            return Directory.GetFiles(path);
        });

        return View(files);
    }
}
Run Code Online (Sandbox Code Playgroud)