2013-02-06 193 views
0

在.Net框架4.5異步和await關鍵字被引入做異步調用。異步調用使用異步和等待

我也在web應用程序中使用過它們。我開始知道這也可以通過做代表完成。

下面是展示如何調用異步完成

   Public void binddata() 
       { 
       certificate = HelperMethods.GetStoreCertifcate(Thumbprint); 
       ListHostedServices(SubscriptionId, certificate, Version); 
       hostedservicesview.ActiveViewIndex = 0; 
       ListStorageAccounts(SubscriptionId, certificate, Version); 
       } 

public async void ListHostedServices(string subscriptionId, X509Certificate2 certificate, string version) 
     { 

      string hittingUri = String.Format("https://management.core.windows.net/{0}/" + "services/hostedservices",SubscriptionId); 
      XmlDocument responsebody= await HelperMethods.GetXmlDocument(hittingUri, certificate, version); 

      if (responsebody != null) 
      { 
       var result = responsebody.GetElementsByTagName("HostedServiceProperties"); 



       hostedservices = new DataTable(); 
       hostedservices.Columns.Add("Url"); 
       hostedservices.Columns.Add("ServiceName"); 

       hostedservices.Columns.Add("Location"); 
       hostedservices.Columns.Add("Label"); 
       hostedservices.Columns.Add("Status"); 
       hostedservices.Columns.Add("DateCreated"); 
       hostedservices.Columns.Add("DateLastModified"); 
       foreach (XmlNode hsnode in result) 
       { 
        DataRow hsrow = hostedservices.NewRow(); 
        hsrow["Url"] = hsnode.ParentNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Url").Any() ? 
          hsnode.ParentNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Url").First().InnerText : string.Empty; 
        hsrow["ServiceName"] = hsnode.ParentNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "ServiceName").Any() ? 
          hsnode.ParentNode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "ServiceName").First().InnerText : string.Empty; 
        hsrow["Location"] = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Location").Any() ? 
          hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Location").First().InnerText : string.Empty; 

        // IF location is empty, it means affinity group is returned, Pull location from affinity group 
        if (String.IsNullOrEmpty(hsrow["Location"].ToString())) 
        { 
         string affnitygroup = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "AffinityGroup").Any() ? 
          hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "AffinityGroup").First().InnerText : string.Empty; 

         certificate = HelperMethods.GetStoreCertifcate(Thumbprint); 
         hsrow["Location"] = await HelperMethods.GetAffinityGroupLocation(subscriptionId, certificate, Version, affnitygroup); 


        } 
        hsrow["Label"] = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Label").Any() ? 
          hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Label").First().InnerText : string.Empty; 
        hsrow["Status"] = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Status").Any() ? 
         hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "Status").First().InnerText : string.Empty; 
        hsrow["DateCreated"] = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "DateCreated").Any() ? 
         hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "DateCreated").First().InnerText : string.Empty; 
        hsrow["DateLastModified"] = hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "DateLastModified").Any() ? 
         hsnode.ChildNodes.OfType<XmlElement>().Where(x => x.Name == "DateLastModified").First().InnerText : string.Empty; 
        hostedservices.Rows.Add(hsrow); 

       } 
       lbl_count.Text = hostedservices.Rows.Count.ToString(); 
       HostedServicesList.DataSource = hostedservices; 
       HostedServicesList.DataBind(); 

      } 

      else 
      { 

      } 




     } 

**XmlDocument responsebody= await HelperMethods.GetXmlDocument(hittingUri, certificate, version);** 
The method definition is as follows 
public static async Task<XmlDocument> GetXmlDocument(string hittingUrl, X509Certificate2 certificate, string Version) 
     { 
      HttpWebRequest request; 
       XmlDocument responsebody = new XmlDocument(); 
      // string hittingUri = "https://management.core.windows.net/{0}/" + "services/hostedservices"; 
      Uri uri = new Uri(hittingUrl); 


      request = (HttpWebRequest)HttpWebRequest.Create(uri); 

      request.Method = "GET"; 
      request.Headers.Add("x-ms-version", Version); 

      request.ClientCertificates.Add(certificate); 
      request.ContentType = "application/xml"; 




      HttpWebResponse webresponse= null; 

      try 
      { 
       webresponse = (HttpWebResponse)await request.GetResponseAsync(); 

      } 
      catch (Exception) 
      { 

      } 

      HttpStatusCode statuscode = webresponse.StatusCode; 
      if (webresponse.ContentLength > 0) 
      { 
       using (XmlReader reader =XmlReader.Create(webresponse.GetResponseStream())) 
       { 
        responsebody.Load(reader); 


       } 
      } 

      if (statuscode.Equals(HttpStatusCode.OK)) 
      { 
       return responsebody; 
      } 
      else 
      { 
       return null; 
      } 


     } 

同樣上述2種方法也有同類房源的我示例代碼段。

它需要大約12-15秒來檢索11 + 19 + 6記錄的數據。

難道你們可以幫我優化這段代碼,使它更快。

回答

0

首先你需要分析你的代碼,看看你到底在哪裏丟失了你的時間。如果GetXMLDocument佔用大部分時間,那麼它可能是服務器沒有作爲響應

除此之外,我的猜測是你的foreach循環花費的時間最多,因爲你基本上搜索所有這裏的每個聲明中的元素。

這樣做的另一種方式可能是

Dictionary<string, string> nvpairsForColumns = new Dictionary { "Url", String.Empty }; // add all valid column headers here 
foreach(var xelement in hsnode.ParentNode.ChildNodes.OfType<XmlElement>) 
{ 
    if(nvparisForColumns.ContainsKey(xelement.Name) 
    && String.IsNullOrEmpty(nvpairsForColumns[xlement.Name])) // assumption String.Empty is not a valid entry else keep another Dictionary<string,bool> to tag when done with first 
    { 
    nvpairsForColumns[xelement.Name] = xelement.InnerText; 
    } 

}