首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Lazy<T> MVC控制器中使用ASP.NET?

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

Stack Overflow用户
提问于 2011-09-21 02:32:08
回答 4查看 1.8K关注 0票数 6

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

所以我想,为什么不让它静止下来。因此,我认为可以在二次检查锁定 4.0中利用Lazy<T>的使用,而不是使用.NET。调用昂贵的服务一次而不是多次。

因此,如果这是我的pseduo代码,我如何使用Lazy<T>来更改它。对于这个示例,我将使用File System作为昂贵的资源,因此在这个示例中,我希望每次请求调用该ActionMethod时,不要从目标路径获取所有文件,而是希望使用Lazy来保存该文件列表。当然,这是第一次打电话。

下一个假设:如果内容被更改,不要担心。这超出了范围。

代码语言:javascript
复制
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);
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-21 02:39:46

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

ConcurrentDictionary听起来像是更接近你想要的东西。

代码语言:javascript
复制
// 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);
    }
}
票数 5
EN

Stack Overflow用户

发布于 2011-09-21 02:50:52

我同意格雷格的观点,Lazy<>在这里是不合适的。

您可以尝试使用asp.net缓存缓存文件夹的内容,使用_foo.PathToFiles作为您的密钥。这比Lazy<>有一个优点,您可以控制缓存的生存期,这样它就可以每天或每周重新获取内容,而无需重新启动应用程序。

此外,缓存对您的服务器是友好的,因为如果没有足够的内存来支持缓存,缓存将优雅地降级。

票数 4
EN

Stack Overflow用户

发布于 2011-09-21 03:00:40

当您不确定是否需要该资源时,Lazy<T>工作得最好,因此只有在实际需要时才能及时加载它。这个操作总是会加载资源,但是由于它很昂贵,您可能想要缓存它吗?你可以试试这样的方法:

代码语言:javascript
复制
public ActionResult PewPew()
{
    MyModel model;
    const string cacheKey = "resource";
    lock (controllerLock)
    {
        if (HttpRuntime.Cache[cacheKey] == null)
        {
            HttpRuntime.Cache.Insert(cacheKey, LoadExpensiveResource());
        }
        model = (MyModel) HttpRuntime.Cache[cacheKey];
    }

    return View(model);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7493946

复制
相关文章

相似问题

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