Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RazorEngine中的模板是如何缓存的?_Razor - Fatal编程技术网

RazorEngine中的模板是如何缓存的?

RazorEngine中的模板是如何缓存的?,razor,Razor,调用RazorEngine.Razor.Compile()时,编译后的模板存储在哪里 程序重新启动后是否可用?如果内存不足,它会被转储吗 我正在一个()项目中使用RazorEngine。应用程序重新启动后,预编译模板是否可用 将它们存储在HttpContext.Cache中是否更有意义? 如果我这样做了,那么使用另一个绕过内部缓存的函数(而不是Compile)会更有意义吗?有没有一种方法可以执行ITemplate并将模型传递给它 RazorEngine.Razor.Parse()是否进行缓存?还

调用
RazorEngine.Razor.Compile()
时,编译后的模板存储在哪里

程序重新启动后是否可用?如果内存不足,它会被转储吗

我正在一个()项目中使用
RazorEngine
。应用程序重新启动后,预编译模板是否可用

将它们存储在
HttpContext.Cache
中是否更有意义? 如果我这样做了,那么使用另一个绕过内部缓存的函数(而不是
Compile
)会更有意义吗?有没有一种方法可以执行
ITemplate
并将模型传递给它


RazorEngine.Razor.Parse()是否进行缓存?还是每次都重新编译模板?

当前,RazorEngine编译模板后,它们将加载到内存中。这些程序集仅保留在内存中,不会在应用程序的生存期之后继续

我正在考虑添加对将这些程序集编译为文件的支持,但这将是未来的版本

如果调用
Razor.Parse
并传入模板的名称,它将尝试

  • 检查内存中程序集的缓存以查找具有相同名称的程序集
  • 无效模板内容的缓存已更改
  • 缓存新编译的模板

  • 我已将此应用于2014年1月底安装的RazorEngine 3.4.1.0

    关键是调用昂贵的
    Razor.Compile(content,name)
    将模板放入缓存,然后调用廉价的
    Razor.Run(name,model)
    执行模板

    public abstract class SqlTemplate<T>: TemplateBase<T>
    {
        public string RenderPartial(string templateName, object model = null)
        {
            // loading a template might be expensive, so be careful to cache content
            if (Razor.Resolve(templateName) == null)
            {
                // we've never seen this template before, so compile it and stick it in cache.
                var templateContent = GetTemplateContent(templateName);
                Razor.Compile(templateContent, templateName);
            }
    
            // by now, we know we've got a the template cached and ready to run; this is fast
            var renderedContent = Razor.Run(templateName, model); 
            return renderedContent;
        }
    
        private string GetTemplateContent(string templateName)
        {
            ... your implementation here
        }
    }
    
    请记住,读取模板内容可能会很昂贵——比如,需要从磁盘读取——所以我的解决方案只获取一次模板内容。这可能是太多的缓存为您,所以小心

    下面是我在自定义
    TemplateBase
    子类中使用的
    RenderPartial
    方法。对于同一模板的多个调用,它运行得非常快

    public abstract class SqlTemplate<T>: TemplateBase<T>
    {
        public string RenderPartial(string templateName, object model = null)
        {
            // loading a template might be expensive, so be careful to cache content
            if (Razor.Resolve(templateName) == null)
            {
                // we've never seen this template before, so compile it and stick it in cache.
                var templateContent = GetTemplateContent(templateName);
                Razor.Compile(templateContent, templateName);
            }
    
            // by now, we know we've got a the template cached and ready to run; this is fast
            var renderedContent = Razor.Run(templateName, model); 
            return renderedContent;
        }
    
        private string GetTemplateContent(string templateName)
        {
            ... your implementation here
        }
    }
    
    如果没有——为什么不给那个人一张赞成票呢?:)


    编辑-如果需要以更精细的方式执行缓存,则需要使用不同的方法,使用
    RazorEngineTemplateService
    ITemplateResolver

    这是一段起始代码

        public static RazorEngineTemplateService CreateService(ITemplateResolver resolver, ICollection<string> namespaces)
        {
            Check.IsNotNull(resolver, "resolver");
            var config = new TemplateServiceConfiguration();
            config.BaseTemplateType = typeof(PlainTextTemplate<>);
            config.EncodedStringFactory = new RazorEngine.Text.RawStringFactory();
            config.Resolver = resolver;
            config.Namespaces = new HashSet<string>(namespaces);
    
            var service = new RazorEngineTemplateService(config);
            return service;
        }
    
    publicstaticrazorenginetemplateservice创建服务(ITemplateResolver解析器,ICollection命名空间)
    {
    检查.IsNotNull(解析器,“解析器”);
    var config=new TemplateServiceConfiguration();
    config.BaseTemplateType=typeof(PlainTextTemplate);
    config.EncodedStringFactory=new RazorEngine.Text.RawStringFactory();
    config.Resolver=Resolver;
    config.Namespaces=newhashset(名称空间);
    var服务=新的RazorEngineTemplateService(配置);
    回程服务;
    }
    

    ITemplateResolver
    将模板名称转换为模板内容,因此您可以实现一个从磁盘加载缓存内容的
    CachedFileTemplateResolver

    非常感谢您回答我的问题。我不知道为什么我从来没见过这个。因此,当且仅当我将一个名称传递给Razor.Parse,并且该模板与上次使用相同名称调用Razor.Parse时相同。然后它将使用缓存的程序集,而不是创建新的程序集?@Rabbi是的,这就是它的工作方式。传入模板名称时,我们获取模板内容的哈希代码,并将其与动态编译的类型一起存储在内存缓存中。下次调用它时,如果模板字符串的hashcode没有更改,我们可以自由地实例化模板类型并执行它。如果不是,我们将使缓存中的现有类型无效,并根据新模板内容重新编译。仅供参考,这不是当前RazorEngine中的工作方式。Profilling显示Razor.Parse导致每次web调用延迟2秒。使用Razor.GetTemplate()将其关闭;Razor.Run();正确地为我们触发了缓存。您能给出一个原始调用
    Razor.Parse
    的示例吗?诀窍是调用Compile()一次,然后多次运行(),而不是Parse()。Parse()很昂贵,但Run()很便宜。如果不重新启动应用程序,我如何使缓存无效?恐怕这个解决方案不适合您。我必须为此创建自己的小系统,它使用RazorEngine.Templating.ITemplateResolver类来获取模板内容。我在回答的底部添加了一些启动代码,以防这有助于您沿着正确的道路前进。那么,您是否基本上需要在磁盘上的模板上放置FileWatcher以使缓存无效并动态重新编译它们?是否已经内置了任何东西,或者我需要自己来实现它?这是一个相当古老的答案,我知道接口已经改变了。IIRC这是针对v2.4.2(真的猜测!),但是如果这方面没有任何变化,那么您可以使用文件监视程序,或者在返回模板之前检查文件的最后修改日期。IIRC大热门是解析模板,而不是加载模板,但应用程序的性能特征将建议正确的方法。