2011-11-16 32 views
5

Tôi có đoạn mã sauLàm thế nào để làm cho việc deserialization XML nhanh hơn?

public static object XmlDeserialize(string xml, Type objType) 
{ 
    StringReader stream = null; 
    XmlTextReader reader = null; 
    try 
    { 
     XmlSerializer serializer = new XmlSerializer(objType); 
     stream = new StringReader(xml); // Read xml data 
     reader = new XmlTextReader(stream); // Create reader 
     return serializer.Deserialize(reader); 
    } 
    finally 
    { 
     if(stream != null) stream.Close(); 
     if(reader != null) reader.Close(); 
    } 
} 

Đối tượng chính nó đã được tạo ra thông qua xsd.exe và trông loại như thế này:

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] 
public partial class MyObject { 

    private DemographicsCriteriaStateStartAge[] startAgesField; 

    private DemographicsCriteriaStateEndAge[] endAgesField; 

    private DemographicsCriteriaStateFilter[] selectedFiltersField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlArrayItemAttribute("StartAge", IsNullable=false)] 
    public DemographicsCriteriaStateStartAge[] StartAges { 
     get { 
      return this.startAgesField; 
     } 
     set { 
      this.startAgesField = value; 
     } 
    } 
    ... 

Phương pháp này thường được gọi là như thế này:

var obj = (MyObject) XmlDeserialize(someXmlString, typeof(MyObject)); 

Dòng mã sau luôn mất một khoảng thời gian khá lớn (so với mọi thứ khác):

XmlSerializer serializer = new XmlSerializer(objType); 

Điều gì đang xảy ra ở đây, ví dụ: là nó biên dịch một hội đồng deserialization trong nền? Tại sao vấn đề hiệu suất?

Tôi có thể làm gì để cải thiện vấn đề hiệu suất này?

+0

Một mặt lưu ý, thay vì 'thử … Cuối cùng, bạn có thể sử dụng 'using'. – svick

Trả lời

5

Có, nó đang tạo động một hội đồng tuần tự hóa tại thời gian chạy. Bạn có thể thay đổi hành vi này trong Visual Studio. Đi đến các thuộc tính của dự án và phần xây dựng. Có một thiết lập cho "Generate serialization assemblies" đặt nó thành true. Điều này sẽ tạo ra một tập tin như YourProject.XmlSerialiser.dll khi bạn biên dịch và sẽ dừng nút cổ chai này trong thời gian chạy. Tuy nhiên,

Một ngoại lệ cần lưu ý là cài đặt này chỉ áp dụng cho các loại proxy (ví dụ: proxy dịch vụ web và các loại tương tự). Để thực sự buộc Visual Studio 2010 tạo các hội đồng tuần tự cho các kiểu thông thường, người ta phải lộn xộn với tệp dự án (.csproj) và loại bỏ/proxytypes khỏi cuộc gọi Sgen hoặc tạo bước sau xây dựng để gọi sgen.exe theo cách thủ công trên assembly.

+0

Tôi có một loạt các hội đồng. Tôi có đặt cài đặt cho EXE chính hoặc cho các hội đồng DLL phụ thuộc không? Btw, tôi đã thực hiện tất cả điều này và không thấy bất kỳ tệp YourProject.XmlSerialiser.dll nào trong bin/debug. – AngryHacker

+0

Tôi chỉ sử dụng nó với proxy web và có vẻ như có một số cuộc tranh luận về việc liệu có một lỗi ở đây http://connect.microsoft.com/VisualStudio/feedback/details/123088/project-does-not-generate- serialization-assembly-even-when-specific-tell-to-do-do-vậy. Để biết thêm chi tiết kiểm soát hạt nhìn vào công cụ exe tài liệu ở đây http://msdn.microsoft.com/en-us/library/bk3w6240(v=vs.80).aspx –

+0

Tôi nghĩ rằng bạn sẽ cần một hội đồng serialization cho mỗi hội đồng bình thường . –

4

Hãy thử bộ nhớ đệm trường hợp của các XmlSerializer đối với từng loại ở cấp lớp, do đó bạn không cần phải tạo lại nó mỗi lần nếu cùng loại được sử dụng:

class Foo 
{ 
    private static Dictionary<Type, XmlSerializer> xmls = new Dictionary<Type, XmlSerializer>(); 

    // ... 

    public static object XmlDeserialize(string xml, Type objType) 
    { 
     StringReader stream = null; 
     XmlTextReader reader = null; 
     try 
     { 
      XmlSerializer serializer; 
      if(xmls.Contains(objType)) { 
       serializer = xmls[objType]; 
      } 
      else { 
       serializer = new XmlSerializer(objType); 
       xmls[objType] = serializer; 
      }   

      stream = new StringReader(xml); // Read xml data 
      reader = new XmlTextReader(stream); // Create reader 
      return serializer.Deserialize(reader); 
     } 
     finally 
     { 
      if(stream != null) stream.Close(); 
      if(reader != null) reader.Close(); 
     } 
    } 
} 
+0

Đây là câu trả lời của tôi khi tôi phát hiện ra mất bao lâu để xây dựng một XmlSerializer cho một lớp đơn giản. Nhưng tôi nghĩ rằng bộ nhớ đệm xảy ra trong lớp XmlSerializer anyway, bởi vì lần thứ hai bạn tạo một XmlSerializer cho một loại nhất định, nó không mất gần như lâu dài. – markmuetz

Các vấn đề liên quan