Como preencher o datagrid no thread de segundo plano com a vinculação de dados usando Visual translation from VPE for Csharp

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 318607
Este artigo foi arquivado. É oferecido "como está" e não será mais atualizado.
Para uma versão deste artigo do Microsoft Visual Basic. NET, consulte 318604.

Este artigo se refere aos seguintes namespaces Microsoft .NET Framework Class Library:
  • System.Threading
  • System.Data
  • System.Data.SqlClient
Sumário
Este artigo passo a passo mostra como consultar um banco de dados em um segmento de plano de fundo e usar ligação de dados para exibir os resultados em um objeto DataGrid .

Quando consultas grandes para um banco de dados são executadas, o aplicativo pode deixar de responder por um longo período de tempo. Para evitar esse comportamento e diminuir o tempo de espera do usuário, a consulta pode ser executada em um segmento de plano de fundo, liberando o aplicativo para outras tarefas até que os dados são retornados do banco de dados e fazer a ligação dos dados é executada.

Requisitos

A lista a seguir descreve o hardware recomendado, software, infra-estrutura de rede e service packs que você precisa:
  • Microsoft Visual Studio .NET
  • Acesso ao banco de dados de exemplo Northwind

Plano de fundo

Por design, métodos de controle ou formulário do Windows não podem ser chamados em um segmento diferente daquele que criou o formulário ou controle. Se você tentar fazer isso, uma exceção é lançada. Dependendo do tratamento de exceção implementado em seu código, essa exceção pode causar seu aplicativo finalizar. Se nenhum tratamento de exceção é implementado, a seguinte mensagem de erro é exibida:
Uma exceção sem tratamento do tipo 'System.ArgumentException' ocorreu em system.windows.forms.dll

Obter informações adicionais: controles criados em um segmento não podem ser pai para um controle em um thread diferente.
A exceção é lançada como Windows Forms são baseados em um modelo single-threaded apartment (STA). Windows Forms podem ser criados em qualquer segmento; após a criação, no entanto, eles não podem ser alternados para um thread diferente. Além disso, os métodos de formulário do Windows não podem ser acessados em outro thread; isso significa que todas as chamadas de método devem ser executadas no thread que criou o formulário ou controle.

As chamadas de método originados fora do segmento de criação devem ser empacotadas (executado) no segmento de criação. Para fazer isso assincronamente, o formulário tem um método BeginInvoke que força o método a ser executado no thread que criou o formulário ou controle. A chamada do método síncrono é feita com uma chamada para o método Invoke .

Criar o aplicativo Windows Forms

Esta seção descreve como criar um aplicativo Windows Forms que consulta um banco de dados em um segmento de plano de fundo e usa o método BeginInvoke para executar ligação de dados em um DataGrid .
  1. Inicie o Visual Studio NET..
  2. Criar um novo projeto, selecione translation from VPE for Csharp Visual como o Tipo de projeto e usar o modelo Windows Application.
  3. Adicionar um objeto de botão ao formulário e alterar sua propriedade Text para "Consulta no segmento".
  4. Adicionar outro botão ao formulário e alterar sua propriedade Text para "No formulário de consulta".
  5. Adicionar um rótulo ao formulário e desmarque sua propriedade Text .
  6. Adicione um TextBox ao formulário.
  7. Adicione um DataGrid ao formulário.
  8. Clique com o botão direito do formulário e, em seguida, clique em Exibir código ; Isso exibe o código do seu aplicativo.
  9. Adicionar as seguintes instruções using à parte superior da página para os namespaces Threading e SqlClient :
       using System.Threading;   using System.Data.SqlClient;
  10. Adicione o seguinte código imediatamente abaixo do código Windows Forms Designer gerado:
       static Form1 MyForm;      Thread UpdateThread;   ThreadStart UpdateThreadStart = new ThreadStart(QueryDataBase);   static MethodInvoker CallDataBindToDataGrid = new MethodInvoker(DataBindToDataGrid);   static DataSet MyDataSet;   static SqlDataAdapter MyDataAdapter;   static string MyQueryString = "SELECT [Order Details].*, Orders.CustomerID, Orders.EmployeeID, Orders.OrderDate FROM [Order Details] CROSS JOIN Orders";   static SqlConnection MyConnection = new SqlConnection("data source=localhost;initial catalog=Northwind;integrated security=SSPI;");
    Observação A consulta usada nesta demonstração é um produto cartesiano que retorna linhas sobre 165,000 do banco de dados Northwind . A quantidade de dados retornados é grande para que a capacidade de resposta do formulário pode ser demonstrada.
  11. Abra o modo de exibição Design de formulários do Windows.
  12. Clique duas vezes o botão de consulta no thread e cole o seguinte código no evento Click para este botão:
       UpdateThread = new Thread(UpdateThreadStart);   UpdateThread.Name = "Update Thread";   UpdateThread.IsBackground = true;   UpdateThread.Start();
  13. Abra novamente o modo de design e, em seguida, clique duas vezes o botão de consulta no formulário . Cole o seguinte código no evento Click para este botão:
       QueryDataBase();
  14. Cole o seguinte código abaixo os eventos de botão que você adicionou nas etapas anteriores:
       // Sub routine that is to be executed on Form's thread.   static void DataBindToDataGrid()   {      MyForm.dataGrid1.DataSource = MyDataSet;      MyForm.dataGrid1.DataMember = "MyTable";      MyDataSet = null;      MyDataAdapter = null;   }   // Sub routine used by the background thread to query database.   static void QueryDataBase()   {      MyDataSet = new DataSet();      MyConnection.Open();      MyDataAdapter = new SqlDataAdapter(MyQueryString, MyConnection);      MyForm.label1.Text = "Filling the DataSet";      MyDataAdapter.Fill(MyDataSet, "MyTable");      MyConnection.Close();      MyForm.label1.Text = "DataSet Filled";      MyForm.BeginInvoke(CallDataBindToDataGrid);	   }
    sub essas rotinas são usadas pelo segmento de plano de fundo para consultar o banco de dados e vincular dados ele para DataGrid localizado no Windows Form quando o primeiro botão é clicado. O evento Click do botão segundo chama a rotina QueryDataBase Sub diretamente e será executado no Windows Form thread.
  15. Modificar a função principal para parecer da seguinte maneira:
       MyForm = new Form1();   Application.Run(MyForm);
  16. Pressione CTRL + SHIFT + B para criar seu aplicativo.

Demonstração

Para ver o benefício obtido usando um thread de segundo plano para consultar o banco de dados, siga estas etapas:
  1. Pressione CTRL+F5 para executar o aplicativo sem depuração.
  2. Clique no botão Query no formulário . Isso começa a consulta no thread de Windows Forms. Se você, em seguida, tentar inserir texto na caixa de texto é exibida no formulário, o aplicativo não responde. Depois que a consulta for concluída (Isso pode levar algum tempo, dependendo do seu computador), o DataGrid exibe os resultados da consulta.
  3. Clique no botão consultar no thread . Isso cria um thread de plano de fundo que consulta o banco de dados e mantém o aplicativo responsivo a interação do usuário. Para ver isso, clique no botão e digite algum texto na caixa de texto no formulário.

Completa listagem de código

   using System;   using System.Drawing;   using System.Collections;   using System.ComponentModel;   using System.Windows.Forms;   using System.Data;   using System.Threading;   using System.Data.SqlClient;   namespace DataGridThread   {      /// <summary>      /// Summary description for Form1.      /// </summary>      public class Form1 : System.Windows.Forms.Form      {         private System.Windows.Forms.DataGrid dataGrid1;         private System.Windows.Forms.Button button1;         private System.Windows.Forms.Label label1;         private System.Windows.Forms.Button button2;	 private System.Windows.Forms.TextBox textBox1;	 /// <summary>	 /// Required designer variable.	 /// </summary>	 private System.ComponentModel.Container components = null;         public Form1()	 {	    // 	    // Required for Windows Form Designer support	    // 	    InitializeComponent();	    // 	    // TODO: Add any constructor code after InitializeComponent call	    // 	 } 	 /// <summary>	 /// Clean up any resources being used.	 /// </summary>	 protected override void Dispose( bool disposing )	 {	    if( disposing )	    {	       if (components != null) 	       {	          components.Dispose();	       }	    }	    base.Dispose( disposing );	 }	 #region Windows Form Designer generated code	 /// <summary>	 /// Required method for Designer support - do not modify	 /// the contents of this method with the code editor.	 /// </summary>	 private void InitializeComponent()	 {	    this.dataGrid1 = new System.Windows.Forms.DataGrid();	    this.button1 = new System.Windows.Forms.Button();	    this.label1 = new System.Windows.Forms.Label();	    this.button2 = new System.Windows.Forms.Button();	    this.textBox1 = new System.Windows.Forms.TextBox();	    ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();	    this.SuspendLayout();	    // 	    // dataGrid1	    // 	    this.dataGrid1.DataMember = "";	    this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;	    this.dataGrid1.Location = new System.Drawing.Point(8, 8);	    this.dataGrid1.Name = "dataGrid1";	    this.dataGrid1.Size = new System.Drawing.Size(736, 208);	    this.dataGrid1.TabIndex = 0;	    // 	    // button1	    // 	    this.button1.Location = new System.Drawing.Point(16, 232);	    this.button1.Name = "button1";	    this.button1.Size = new System.Drawing.Size(120, 23);	    this.button1.TabIndex = 1;	    this.button1.Text = "Query on Thread";	    this.button1.Click += new System.EventHandler(this.button1_Click);	    // 	    // label1	    // 	    this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 15F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));	    this.label1.Location = new System.Drawing.Point(16, 276);	    this.label1.Name = "label1";	    this.label1.Size = new System.Drawing.Size(720, 24);	    this.label1.TabIndex = 2;	    // 	    // button2	    // 	    this.button2.Location = new System.Drawing.Point(144, 232);	    this.button2.Name = "button2";	    this.button2.Size = new System.Drawing.Size(112, 23);	    this.button2.TabIndex = 3;	    this.button2.Text = "Query on Form";	    this.button2.Click += new System.EventHandler(this.button2_Click);	    // 	    // textBox1	    // 	    this.textBox1.Location = new System.Drawing.Point(268, 232);	    this.textBox1.Name = "textBox1";	    this.textBox1.Size = new System.Drawing.Size(472, 20);	    this.textBox1.TabIndex = 4;	    this.textBox1.Text = "";	    // 	    // Form1	    // 	    this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);	    this.ClientSize = new System.Drawing.Size(752, 330);	    this.Controls.AddRange(new System.Windows.Forms.Control[] { this.textBox1, this.button2, this.label1, this.button1, this.dataGrid1});	    this.Name = "Form1";	    this.Text = "Form1";	    this.Load += new System.EventHandler(this.Form1_Load);	    ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();	    this.ResumeLayout(false);	 }	 #endregion	 /// <summary>	 /// The main entry point for the application.	 /// </summary>	 /// 	 static Form1 MyForm;	 	 Thread UpdateThread;	 ThreadStart UpdateThreadStart = new ThreadStart(QueryDataBase);	 static MethodInvoker CallDataBindToDataGrid = new MethodInvoker(DataBindToDataGrid);	 static DataSet MyDataSet;	 static SqlDataAdapter MyDataAdapter;	 static string MyQueryString = "SELECT Products.* FROM [Order Details] CROSS JOIN Products";	 static SqlConnection MyConnection = new SqlConnection("data source=localhost;initial catalog=Northwind;integrated security=SSPI;");	 [STAThread]	 static void Main() 	 {	    MyForm = new Form1();	    Application.Run(MyForm);	 }	 private void Form1_Load(object sender, System.EventArgs e)	 {			 }	 private void button1_Click(object sender, System.EventArgs e)	 {	    UpdateThread = new Thread(UpdateThreadStart);	    UpdateThread.Name = "Update Thread";	    UpdateThread.IsBackground = true;	    UpdateThread.Start();	 }	 private void button2_Click(object sender, System.EventArgs e)	 {	    QueryDataBase();	 }	 static void DataBindToDataGrid()	 {	    MyForm.dataGrid1.DataSource = MyDataSet;	    MyForm.dataGrid1.DataMember = "MyTable";	    MyDataSet = null;	    MyDataAdapter = null;	 }	 static void QueryDataBase()	 {	    MyDataSet = new DataSet();	    MyConnection.Open();	    MyDataAdapter = new SqlDataAdapter(MyQueryString, MyConnection);	    MyForm.label1.Text = "Filling the DataSet";	    MyDataAdapter.Fill(MyDataSet, "MyTable");	    MyConnection.Close();	    MyForm.label1.Text = "DataSet Filled";	    MyForm.BeginInvoke(CallDataBindToDataGrid);		 }      }   }
Referências
Exemplo de controle de formulários Windows multithread
http://msdn2.microsoft.com/en-us/library/3s8xdz5c(vs.71).aspx

Propriedades

ID do Artigo: 318607 - Última Revisão: 12/07/2015 09:04:55 - Revisão: 3.4

Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# .NET 2003 Standard Edition, Microsoft ADO.NET 1.0, Microsoft .NET Framework 1.1

  • kbnosurvey kbarchive kbmt kbhowtomaster kbsqlclient kbsystemdata kbthread KB318607 KbMtpt
Comentários