C# 创建多个xml文件并将其导出为一个zip文件的最佳方法是什么

C# 创建多个xml文件并将其导出为一个zip文件的最佳方法是什么,c#,asp.net-mvc,razorengine,C#,Asp.net Mvc,Razorengine,我的项目在ASP.NETMVC中,现在我正在使用Razor引擎服务(RazorEngineService.RunCompile)创建多个XML文件,并将其作为单个Zip文件导出 但问题是,当我们每次传递模型对象来处理模板并将其作为单独的XML文件返回并完成整个操作时,完成整个内容的导出需要更多的时间(10个对象大约需要40秒) 我目前的方法有什么问题吗?或者我现在做得对吗?如果我在这种方法中有任何错误,请指导我 private FileInfo Export(List<Model>

我的项目在ASP.NETMVC中,现在我正在使用Razor引擎服务(RazorEngineService.RunCompile)创建多个XML文件,并将其作为单个Zip文件导出

但问题是,当我们每次传递模型对象来处理模板并将其作为单独的XML文件返回并完成整个操作时,完成整个内容的导出需要更多的时间(10个对象大约需要40秒)

我目前的方法有什么问题吗?或者我现在做得对吗?如果我在这种方法中有任何错误,请指导我

private FileInfo Export(List<Model> modelList)
  {
        string timeStr = Datetime.Now.ToString();
        string archiveFileName = "Main.zip";
        string archivePath = Path.Combine(_reportFolderPath, archiveFileName);

        using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
    {
        foreach (var list in modelList)
        {
            string fileName = model.name + model.Id;
            string filePath = GetModelExport(list, fileName, timeStr);
            archive.CreateEntryFromFile(filePath, fileName + ".xml");
        }
        archive.Dispose();
    }
    return new FileInfo(archivePath);
}

private string GetModelExport(Model model, string fileName, string timeStr)
{
    var processedTemplate = ProcessTemplate(model, TemplateName, TemplateKey);
    string reportFilelName = fileName + "_" + timeStr + ".xml";
    string filePath = Path.Combine(_reportFolderPath, reportFilelName);

    using (var file = new StreamWriter(filePath))
    {
        file.Write(processedTemplate);
    }
    return filePath;
}

private string ProcessTemplate(Model model, string templateName, string templateKey)
    {
        var templateFilePath = Path.Combine(_reportTemplateFolder, templateName);
        return ReportUtils.ProcessTemplate(templateFilePath, templateKey, model);
    }
public static string ProcessTemplate(string templatePath, string templateKey, object model = null)
{
    var templateService = RazorEngineService.Create();
    var result = templateService.RunCompile(File.ReadAllText(templatePath), templateKey, null, model);

    return result;
}
私有文件信息导出(列表模型列表)
{
字符串timeStr=Datetime.Now.ToString();
字符串archiveFileName=“Main.zip”;
字符串archivePath=Path.Combine(_reportFolderPath,archiveFileName);
使用(ZipArchive archive=ZipFile.Open(archivePath,ZipArchiveMode.Create))
{
foreach(模型列表中的变量列表)
{
字符串文件名=model.name+model.Id;
字符串filePath=GetModelExport(列表、文件名、timeStr);
CreateEntryFromFile(文件路径,文件名+“.xml”);
}
archive.Dispose();
}
返回新的FileInfo(archivePath);
}
私有字符串GetModelExport(模型模型、字符串文件名、字符串时间TR)
{
var processedTemplate=ProcessTemplate(模型、TemplateName、TemplateKey);
字符串reportFilelName=fileName+“”+timeStr+“.xml”;
字符串filePath=Path.Combine(_reportFolderPath,reportFilelName);
使用(var file=newstreamwriter(filePath))
{
file.Write(processedTemplate);
}
返回文件路径;
}
私有字符串ProcessTemplate(模型模型、字符串templateName、字符串templateKey)
{
var templateFilePath=Path.Combine(_reportTemplateFolder,templateName);
return ReportUtils.ProcessTemplate(templateFilePath、templateKey、model);
}
公共静态字符串ProcessTemplate(字符串templatePath,字符串templateKey,对象模型=null)
{
var templateService=RazorEngineService.Create();
var result=templateService.RunCompile(File.ReadAllText(templatePath),templateKey,null,model);
返回结果;
}

您的一些代码缺失,因此我无法看到整个画面,这是我将从。。。。。祝你好运


public class HolderTempName 
{
    private TemplateService _templateService;
    private Dictionary<string, string> _templateContainer;
    
    public HolderTempName()
    {
        //this will save creating this everytime
        _templateService = RazorEngineService.Create();
        
        //this will hold the template so it does not have to fetch on each loop,
        //if the same template is used.
        _templateContainer = new Dictionary<string, string>();
    }


    //you will need to tweeek this to get the type out 
    private string GetTemplate(string templateName, templatePath)
    {
        if(!_templateContainer.Conatains(templateName))
        {
            var text = File.ReadAllText(templatePath);
            _templateContainer[templateName]  = text;
        }
        return _templateContainer[templateName];
    }


    private FileInfo Export(List<Model> modelList)
    {
        string timeStr = Datetime.Now;
        string archiveFileName = "Main.zip";
        string archivePath = Path.Combine(_reportFolderPath, archiveFileName);


        using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
        {
            foreach (var item in modelList)
            {
                var templateFilePath = Path.Combine(_reportTemplateFolder, TemplateName); //<--TemplateName seems like a local private
                //these should come from where cant see where...
                var template = GetTemplate( TemplateName, templateFilePath)
                
                string modelResponse  = ProcessModel(item,template,TemplateKey ); //<-- why is not passing in the template
                //step 2; 
                //making this above done in parrell and then add aync, but before all that measure what is taking time
                
                string pathname = MakeFileName(_reportFolderPath, reportFilelName, timeStr);
                SaveToDisk(pathname, modelResponse);
                
                string fileName = model.name + model.Id;
                archive.CreateEntryFromFile(filePath, fileName + ".xml");
            }
            archive.Dispose();
        }
        return new FileInfo(archivePath);
    }

    private string MakeFileName(string path ,string filename, string tStamp)
    {
        string reportFilelName = fileName + "_" + timeStr + ".xml";
        string filePath = Path.Combine(_reportFolderPath, reportFilelName);
        return filePath;
    }

    private void SaveToDisk(string filePath, string content)
    {
        using (var file = new StreamWriter(filePath))
        {
            file.Write(processedTemplate);
        }
    }
    
    public static string ProcessTemplate(object model, string template, templateKey)
    {
        var result = templateService.RunCompile(template, templateKey, null, model);
        return result;
    }
}

公共类HolderTempName
{
私有模板服务_TemplateService;
私有字典templateContainer;
public HolderTempName()
{
//这将节省每次创建此文件的时间
_templateService=RazorEngineService.Create();
//这将保存模板,因此它不必在每个循环中提取,
//如果使用相同的模板。
_templateContainer=新字典();
}
//你需要仔细检查一下这个才能把字拿出来
私有字符串GetTemplate(字符串templateName、templatePath)
{
if(!\u templateContainer.Conatains(templateName))
{
var text=File.ReadAllText(templatePath);
_templateContainer[templateName]=文本;
}
return _templateContainer[templateName];
}
私有文件信息导出(列表模型列表)
{
字符串timeStr=Datetime.Now;
字符串archiveFileName=“Main.zip”;
字符串archivePath=Path.Combine(_reportFolderPath,archiveFileName);
使用(ZipArchive archive=ZipFile.Open(archivePath,ZipArchiveMode.Create))
{
foreach(模型列表中的变量项)
{

var templateFilePath=Path.Combine(_reportTemplateFolder,TemplateName);//这是真正的代码吗?因为它不只是用
string timeStr=Datetime编译。现在;
。有多种方法可以加快编译速度:并行处理、将模板保留在内存中、重用
RazorEngineService
实例…@CamiloTerevinto是的,这是真正的代码。基本上在实际情况下,我们有单独的代码要转换字符串的时间。可能只是例如DateTime.Now.ToString()假设每次在一次操作中读取不同的文件,并行化应该相当简单。查看
Parallel.ForEach
,您可能需要一个
ConcurrentBag
,具体取决于您的方法it@CamiloTerevinto,感谢您的评论,我将尝试使用Parellel.ForEach并通过我是通过重复使用RazorEngineService实例得到这一点的,但是如果将模板保留在内存中,我就没有得到这一点。你的意思是说加载模板路径并将其保留在内存中,而不是每次读取完整的路径?@CamiloTerevinto在构建报表层时加载报表模板,并且只加载一次e now Report Template它正在创建中,在生成模板的步骤之间被删除,现在它工作正常,没有任何问题,非常感谢。感谢您的回答,我已经修改了一些与您的答案类似的内容,并且成功了。