2017-06-21 45 views
0

我最近在我的应用程序中添加了一些搜索功能。它运行良好,但有一个项目名为Folder,因此需要我进行一些Web服务调用。我一次最多返回100个项目,如果所有100个项目都是特定类型的,并且每个项目需要3或4个Web服务呼叫,则需要长达30秒才能获取信息。MVC - 在多个地方延迟加载1个字符串

我得到的信息位是PathPath与PC上的文件路径相同,并且在每个级别都进行新的Web服务调用。如果我删除代码以获取返回的每个项目的此路径,我可以在大约2 - 3秒内将结果呈现给用户,并获得100个结果。这是在我的开发机器上,所以我希望生产速度更快。

我想要做的是在屏幕上载入每个Folder后获得Path。通过这种方式,大部分信息已经在那里供用户在可接受的时间内查看,并且Path稍后载入。

我至今在我的控制方法,该方法将返回Path作为一个字符串:

[HttpGet] 
    public string _SearchGetFolderPath(int folderID) 
    { 
     using (SA sa = new SA()) 
     using (IRWS irws = new IRWS(sa.Ticket)) 
     { 
      return irws.getFolderPathfromFolderID(folderID); 
     } 
    } 

在上述方法中,SA对象是Web服务和IRWS用户身份对象是我保持我的Web服务调用的地方。

然后,我有这个在我看来:

@*Display Each Returned Result*@ 
     @foreach (var item in Model) 
     { 
      <div class="panel panel-default"> 
       <div class="panel-heading clearfix"> 
        <h3 class="panel-title pull-left">@(item.Name)</h3> 
        <span class="pull-right">@item.AspectType.AspectName</span> 
       </div> 
       <div class="panel-body"> 
        <dl class="dl-horizontal"> 
         @foreach (var value in item.FieldValues) 
         { 
          <dt>@value.FieldName</dt> 
          @*Test if Item is a Folder and Field is Path*@ 
         if (item.AspectType.AspectTypeID == -10 && value.FieldName.Contains("Path")) 
         { 
          /*Folder Path - get path*/ 
          // HERE IS WHERE I WOULD LIKE TO LAZY LOAD THE PATH 
         } 
         else if (false) 
         { 

         } 
         else 
         { 
          <dd>@value.FieldValue</dd> 
          } 

         } 
        </dl> 
       </div> 
      </div> 
      <br /> 
     } 

我想这同样工作,如何我的应用程序工作的另一部分。每一个Folder有一个页面,提供更多的信息,我用我的所有用户界面的Telerik,所以我懒加载Folder的孩子在Panel Barhttp://demos.telerik.com/aspnet-mvc/panelbar/ajax)。

任何想法或建议,非常感谢。谢谢。

回答

0

惰性加载在烤到C#中象下面这样的例子一些方法可以帮助:

public class yourClassName { 
    static object _lock = new object(); 
    static IDictionary<string, string> loadedValues = new Dictionary<string, string>(); 


    private string BuildString(int folderID) { 
     if (!loadedValues.ContainsKey(folderID)) // if we dont have the value 
      using (SA sa = new SA()) 
      using (IRWS irws = new IRWS(sa.Ticket)) 
       lock(this) 
        if (loadedValues.ContainsKey(folderID)) // lets check again (maybe in btween the locks other threads did the job) 
         lock(_lock) 
          return loadedValues[folderID]; 
        else // it looks like we dont have it (now it is populated) 
         loadedValues.Add(folderID, irws.getFolderPathfromFolderID(folderID)); 
     return loadedValues[folderID] 
    } 

    [HttpGet] 
    public string _SearchGetFolderPath(int folderID) 
    { 
     return BuildString(folderID); 
    } 

} 

延迟加载大自然为我推荐它,它会要求我知道多一点的逻辑,为什么它用过的。

作为MVC.net世界中的一种替代方案,您可以利用MVC缓存,在这种情况下可以节省更多时间(控制器方法不会被调用并且缓存视图html/tmplate),只需添加作为属性下面一行的你方法

[OutputCache(Duration = 10 /* minutes */, VaryByParam = "folderID")] 

更多关于MVC缓存以下链接

概念以及它是如何工作
https://msdn.microsoft.com/en-us/library/ff648482.aspx

如何给我们e /优化高速缓存
https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/improving-performance-with-output-caching-cs

+0

高速缓存路径的问题是路径可随时更改。 – JohZant

+0

添加了基于文件夹ID位的延迟加载和缓存,希望它有帮助:) 如果值发生更改(如果使用的语句不是昂贵的代码行,但“getFolderPath”是昂贵的线) –

+0

你是正确的,'irws.getFolderPathfromFolderID(folderID)'有一个循环,它将获得下一个孩子的细节,直到它有一个完整的路径。也许我应该让它按照旧式的方式工作......每个路径都有一个按钮。哈哈。 – JohZant