2017-06-21 46 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