我有一个简单的ASP.NET MVC控制器。在一些操作方法中,我访问了一个资源,我会说它很昂贵。
所以我想,为什么不让它静止下来。因此,我认为可以在二次检查锁定 4.0中利用Lazy<T>的使用,而不是使用.NET。调用昂贵的服务一次而不是多次。
因此,如果这是我的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);
}
}发布于 2011-09-21 02:39:46
在您的示例中,Directory.GetFiles的结果取决于_foo的值,该值不是静态的。因此,您不能使用Lazy<string[]>的静态实例作为控制器所有实例之间的共享缓存。
ConcurrentDictionary听起来像是更接近你想要的东西。
// 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);
}
}https://stackoverflow.com/questions/7493946
复制相似问题