Thursday, March 10, 2011

Post 2 - How to: Speedup the heavy data loading from WCF service to datagridview in c# improvements on the client side application

In my previous post on speed up the heavy data loading in datagridview, even though the data is coming to the client in separate chunks the grid is loading only after the data is loaded completely. In this article I am solving that issue using a separate thread to refresh the grid as and when data is pushed to the Data Table.

Following is the code change in the client side application:

Initialize the following variables.

   1: public DataTable dtCustomers { get; set; }
   2:         delegate void Bind_DataTable_to_GridView_Delegate(DataTable dt);
   3:         Thread tBindGrid;


Following is the code change in client side



   1: public Form1()
   2:         {
   3:             InitializeComponent();
   4:  
   5:             // Initilaize the customer data table
   6:             dtCustomers = new DataTable();
   7:             dtCustomers.Columns.Clear();
   8:             dtCustomers.Columns.Add("FirstName");
   9:             dtCustomers.Columns.Add("LastName");
  10:             dtCustomers.Columns.Add("Address");
  11:             // set datasource of the datagridview
  12:             dataGridView1.DataSource = dtCustomers;
  13:             // Initialize the thread with the thread function
  14:             tBindGrid = new Thread(GetAllCustomers);
  15:  
  16:             tBindGrid.SetApartmentState(ApartmentState.STA);
  17:             // Start the thread 
  18:             tBindGrid.Start();
  19:         }
  20:  
  21:         // Thread function
  22:         private void GetAllCustomers()
  23:         {
  24:             DataTable dt = new DataTable();
  25:             dt.Columns.Clear();
  26:  
  27:             dt.Columns.Add("FirstName");
  28:             dt.Columns.Add("LastName");
  29:             dt.Columns.Add("Address");
  30:  
  31:             ChannelFactory<IService> factory = new ChannelFactory<IService>("localhost");
  32:             IService service = factory.CreateChannel();
  33:  
  34:             System.ServiceModel.Channels.Message message = service.GetCustomers();
  35:  
  36:             foreach (List<Customer> customers in GetAllCustomers(message))
  37:             {
  38:                 foreach (Customer item in customers)
  39:                 {
  40:                     DataRow dr = dt.NewRow();
  41:                     dr["FirstName"] = item.FirstName;
  42:                     dr["LastName"] = item.LastName;
  43:                     dr["Address"] = item.Address;
  44:                     
  45:                     dt.Rows.Add(dr);
  46:                 }
  47:                 bind_DataTable_to_GridView(dt);
  48:                 dt.Clear();
  49:             }
  50:         }
  51:  
  52:         // function for binding the datatable datagridview in seperate thread
  53:         private void bind_DataTable_to_GridView(DataTable dt)
  54:         {
  55:  
  56:             if (dataGridView1.InvokeRequired)
  57:             {
  58:                 Bind_DataTable_to_GridView_Delegate del = new Bind_DataTable_to_GridView_Delegate(bind_DataTable_to_GridView);
  59:                 dataGridView1.Invoke(del, new object[] { dt });
  60:             }
  61:             else
  62:             {
  63:                 dtCustomers.Merge(dt);
  64:                 dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;               //Autosizes the gridview 
  65:                 foreach (DataGridViewColumn dgvcol in dataGridView1.Columns)
  66:                 {
  67:                     dgvcol.SortMode = DataGridViewColumnSortMode.NotSortable;
  68:                 }
  69:             }
  70:         }
  71:  
  72:         static IEnumerable<List<Customer>> GetAllCustomers(System.ServiceModel.Channels.Message message)
  73:         {
  74:             XmlReader reader = message.GetReaderAtBodyContents();
  75:  
  76:             XmlSerializer serializer = new XmlSerializer(typeof(Customer[]));
  77:             reader.ReadStartElement("Customer");
  78:  
  79:             while (!reader.EOF && reader.LocalName == "ArrayOfCustomer")
  80:             {
  81:                 Customer[] customer = (Customer[])serializer.Deserialize(reader);
  82:                 yield return customer.ToList<Customer>();
  83:             }
  84:  
  85:             reader.ReadEndElement();
  86:         }

For the time being I have not uploaded the updated source code. You can change the existing source code which is uploaded here. If you need any help please lete me know.


Thanks guys!!!


Anilal Sambasivan

0 comments:

Post a Comment