2017-02-03 16 views
2

下面是增加打開多個多線程但在單線程上調用的方法具有良好性能的新方法的性能的代碼。在多線程上運行的方法的縮放性能C#

所以,請你讓我知道如何儘量減少它在多線程運行而不是(即舊法)

 public List<CEntity> GetSomeFunction(Ent ent) 
    { 
     List<CEntity> lstCE = new List<CEntity>(); 
     this.objEnt = ent; 

     TestObj objTempBal = new objTempBal(); 
     objTempBal.objEnt = ent; 

     System.Diagnostics.Debug.WriteLine("new Method"); 

     Stopwatch stopWatch = new Stopwatch(); 
     stopWatch.Start(); 

     objTempBal.FetchSomeDataAsync(ent).Wait(); 

     stopWatch.Stop(); 

     System.Diagnostics.Debug.WriteLine(String.Format("Elapsed time: {0} -- {1} ", 
     stopWatch.Elapsed.Milliseconds, DateTime.Now)); 

     System.Diagnostics.Debug.WriteLine("old Method"); 

     Stopwatch stopWatch1 = new Stopwatch(); 
     stopWatch1.Start(); 

    List<CEntity> result = null; 
     ResponseApi response = null; 
     try 
     { 
      IWrapper Wrapper = InitializeWrapper(ent); 
      int pageNo = 1; 
      bool createPaging = true; 
      while (createPaging) 
      { 

       SearchCriteria objSC = new SearchCriteria() 
       { 
        //pageSize = this.pageSize, 
        pageSize = "1000", 
        page = pageNo.ToString() 
       }; 
       response = Wrapper.SomeSynchronusAPIMethod(objSC); 
       if (response.Success) 
       { 
        result = (List<CEntity>)response.results; 
        if (result.Count == 0) 
        { 
         createPaging = false; 
        } 
        else 
        { 
         result = result.ToList();       

        } 
        lstCE.AddRange(result); 

       } 
       else { createPaging = false; } 
       pageNo = pageNo + 1; 
      } 
     } 
     catch (Exception ex) 
     { 
      throw; 
     } 

     stopWatch1.Stop(); 
     System.Diagnostics.Debug.WriteLine(String.Format("Elapsed time: {0} -- {1} ", 
      stopWatch1.Elapsed.Milliseconds, DateTime.Now)); 
     return lstCE; 
    } 

public async Task<List<CEntity>> FetchSomeDataAsync(Ent ent) 
{ 

     var tasks = new List<Task<List<CEntity>>>(); 
     int pageCount = 18; 
     List<int> pages = new List<int>(); 

     for (int addItemToList = 1; addItemToList <= pageCount; addItemToList++) 
     { 
      pages.Add(addItemToList); 
     } 
     List<CEntity> resultRange = new List<CEntity>(); 
     foreach (var list in pages.Batch(10)) 
     { 

      foreach (var item in list) 
      { 
       IWrapper Wrapper1 = InitializeWrapper(ent); 
       tasks.Add(Task.Run(() => FetchSomeDataFromSynchronusAPI(Wrapper1, item))); 

      } 
      var results = await Task.WhenAll(tasks); 
      resultRange.AddRange(results.SelectMany(x => x.ToList()).ToList()); 
      tasks = new List<Task<List<CEntity>>>(); 
     } 
     return resultRange; 

} 

    public async Task<List<CEntity>> FetchSomeDataFromSynchronusAPI(IWrapper Wrapper, int pageNo) 
    { 
     System.Diagnostics.Debug.WriteLine("Start pageNo " + pageNo + " -- " + DateTime.Now); 

     List<CEntity> result = null; 
     ResponseApi response = null; 
     SearchCriteria objSC = new SearchCriteria() 
     { 

      pageSize = "1000", 
      page = pageNo.ToString() 
     }; 


     response = Wrapper.SomeSynchronusAPIMethod(objSC); 

     if (response.Success) 
     { 
      result = (List<CEntity>)response.results; 

      result = result.ToList(); 

     } 
     System.Diagnostics.Debug.WriteLine("End pageNo " + pageNo + " -- " + DateTime.Now); 

     return await Task.FromResult<List<CEntity>>(result); 
     //return (result); 
    } 
+0

Wrapper.SomeSynchronusAPIMethod是這種異步方法嗎? –

+0

Wrapper.SomeSynchronusAPIMethod不是異步方法 – Ashutosh

回答

2

無需這是在單個線程運行的方法對新方法的時間等待每批。運行所有任務,並等待頁面之外的所有任務。批處理循環。

  List<CEntity> resultRange = new List<CEntity>(); 

      foreach (var list in pages.Batch(10)) 
      { 

       foreach (var item in list) 
       { 
        IWrapper Wrapper1 = InitializeWrapper(ent); 
        tasks.Add(Task.Run(() => FetchSomeDataFromSynchronusAPI(Wrapper1, item))); 

       } 
      } 

     var results = await Task.WhenAll(tasks); 
     resultRange.AddRange(results.SelectMany(x => x.ToList()).ToList()); 
+0

如果不需要等待每個批次,那麼如何在resultrange中添加結果 – Ashutosh

+0

我現在編輯了答案var results = await Task.WhenAll(tasks);移到循環外部,所以任務列表包含所有頁面的所有任務。結果變量將包含所有任務結果。最後一行將處理所有結果並將它們添加到結果範圍中。 –

+0

但是,這是一個缺陷,一次打開所有頁面的所有線程都會降低服務器的性能。如果有100頁,則服務器上將有100個線程打開。所以我的要求是在一批中處理線程,即執行10個線程的批次,然後是10個線程,等等。 – Ashutosh