Como preencher o DataGrid no thread de segundo plano com a vinculação de dados usando Visual Basic 2005 ou Visual Basic .NET

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: 318604
Para obter uma Microsoft Visual translation from VPE for Csharp .NET versão deste artigo, consulte 318607.
Sumário
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.

Este artigo passo a passo demonstra 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 .

Requisitos

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

Plano de fundo

Por design, Microsoft Windows Forms ou métodos de controle 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 Windows Forms 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 ou Visual Studio 2005.
  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. Adicione as instruções a seguir Importar na parte superior da página para importar os namespaces Threading e SqlClient .
       Imports System.Threading   Imports System.Data.SqlClient					
  10. Adicione o seguinte código imediatamente abaixo de Windows Forms Designer gerado código.
       Dim UpdateThread As Thread   Dim UpdateThreadStart As New ThreadStart(AddressOf QueryDataBase)   Dim CallDataBindToDataGrid As New MethodInvoker(AddressOf Me.DataBindToDataGrid)   Dim MyDataSet As DataSet   Dim MyDataAdapter As SqlDataAdapter   Dim MyQueryString As String = "SELECT Products.* FROM [Order Details] CROSS JOIN Products"   Dim MyConnection As 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 a exibição de design de formulários 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.IsBackground = True   UpdateThread.Name = "UpdateThread"   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.   Public Sub DataBindToDataGrid()      DataGrid1.DataSource = MyDataSet      DataGrid1.DataMember = "MyTable"      MyDataAdapter = Nothing      MyDataSet = Nothing   End Sub   ' Sub routine used by the background thread to query database.   Public Sub QueryDataBase()      MyDataSet = New DataSet()      MyConnection.Open()      Dim cmd As New SqlCommand(MyQueryString, MyConnection)      MyDataAdapter = New SqlDataAdapter(cmd)      Label1.Text = "Filling DataSet"      MyDataAdapter.Fill(MyDataSet, "MyTable")      MyConnection.Close()      Label1.Text = "DataSet Filled"           ' Make asynchronous function call to Form's thread.      Me.BeginInvoke(CallDataBindToDataGrid)   End Sub						
    sub these 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 Forms thread.
  15. 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 em consulta 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.

Listagem de código completo

Imports System.ThreadingImports System.Data.SqlClientPublic Class Form1  Inherits System.Windows.Forms.Form#Region " Windows Form Designer generated code "  Public Sub New()    MyBase.New()    'This call is required by the Windows Form Designer.    InitializeComponent()    'Add any initialization after the InitializeComponent() call.  End Sub  'Form overrides dispose to clean up the component list.  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)    If disposing Then      If Not (components Is Nothing) Then        components.Dispose()      End If    End If    MyBase.Dispose(disposing)  End Sub  'Required by the Windows Form Designer.  Private components As System.ComponentModel.IContainer  'NOTE: The following procedure is required by the Windows Form Designer.  'It can be modified using the Windows Form Designer.    'Do not modify it using the code editor.  Public WithEvents DataGrid1 As System.Windows.Forms.DataGrid  Friend WithEvents Button1 As System.Windows.Forms.Button  Friend WithEvents Button2 As System.Windows.Forms.Button  Friend WithEvents Label1 As System.Windows.Forms.Label  Friend WithEvents TextBox1 As System.Windows.Forms.TextBox  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()    Me.DataGrid1 = New System.Windows.Forms.DataGrid()    Me.Button1 = New System.Windows.Forms.Button()    Me.Button2 = New System.Windows.Forms.Button()    Me.Label1 = New System.Windows.Forms.Label()    Me.TextBox1 = New System.Windows.Forms.TextBox()    CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()    Me.SuspendLayout()    '    'DataGrid1    '    Me.DataGrid1.DataMember = ""    Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText    Me.DataGrid1.Location = New System.Drawing.Point(8, 8)    Me.DataGrid1.Name = "DataGrid1"    Me.DataGrid1.Size = New System.Drawing.Size(688, 276)    Me.DataGrid1.TabIndex = 0    '    'Button1    '    Me.Button1.Location = New System.Drawing.Point(12, 296)    Me.Button1.Name = "Button1"    Me.Button1.Size = New System.Drawing.Size(136, 23)    Me.Button1.TabIndex = 1    Me.Button1.Text = "Query on Thread"    '    'Button2    '    Me.Button2.Location = New System.Drawing.Point(160, 296)    Me.Button2.Name = "Button2"    Me.Button2.Size = New System.Drawing.Size(132, 23)    Me.Button2.TabIndex = 3    Me.Button2.Text = "Query on Form"    '    'Label1    '    Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 15.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))    Me.Label1.Location = New System.Drawing.Point(12, 332)    Me.Label1.Name = "Label1"    Me.Label1.Size = New System.Drawing.Size(680, 23)    Me.Label1.TabIndex = 4    '    'TextBox1    '    Me.TextBox1.Location = New System.Drawing.Point(300, 296)    Me.TextBox1.Name = "TextBox1"    Me.TextBox1.Size = New System.Drawing.Size(392, 20)    Me.TextBox1.TabIndex = 5    Me.TextBox1.Text = ""    '    'Form1    '    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)    Me.ClientSize = New System.Drawing.Size(704, 382)    Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.TextBox1, Me.Label1, Me.Button2, Me.Button1, Me.DataGrid1})    Me.Name = "Form1"    Me.Text = "Form1"    CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()    Me.ResumeLayout(False)  End Sub#End Region  Dim UpdateThread As Thread  Dim UpdateThreadStart As New ThreadStart(AddressOf QueryDataBase)  Dim CallDataBindToDataGrid As New MethodInvoker(AddressOf Me.DataBindToDataGrid)  Dim MyDataSet As DataSet  Dim MyDataAdapter As SqlDataAdapter  Dim MyQueryString As String = "SELECT Products.* FROM [Order Details] CROSS JOIN Products"  Dim MyConnection As New SqlConnection("data source=localhost;initial catalog=northwind;integrated security=SSPI;")  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click    UpdateThread = New Thread(UpdateThreadStart)    UpdateThread.IsBackground = True    UpdateThread.Name = "UpdateThread"    UpdateThread.Start()  End Sub  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click    QueryDataBase()  End Sub  Public Sub DataBindToDataGrid()    DataGrid1.DataSource = MyDataSet    DataGrid1.DataMember = "authors"    MyDataAdapter = Nothing    MyDataSet = Nothing  End Sub  Public Sub QueryDataBase()    MyDataSet = New DataSet()    MyConnection.Open()    Dim cmd As New SqlCommand(MyQueryString, MyConnection)    MyDataAdapter = New SqlDataAdapter(cmd)    Label1.Text = "Filling DataSet"    MyDataAdapter.Fill(MyDataSet, "authors")    MyConnection.Close()    Label1.Text = "DataSet Filled"    Me.BeginInvoke(CallDataBindToDataGrid)  End SubEnd Class				
Observação Você deve alterar o código no Visual Basic 2005. Por padrão, Visual Basic cria dois arquivos para o projeto quando você cria um projeto Windows Forms. Se o formulário é denominado Form1, os dois arquivos que representam o formulário são chamados de Form1.vb e Form1.Designer.vb. Escreva o código no arquivo Form1.vb. O Windows Forms Designer escreve o código no arquivo Form1.Designer.vb. O Windows Forms Designer usa a palavra-chave partial para dividir a implementação de Form1 em dois arquivos separados. Esse comportamento impede que o código gerado pelo designer sendo intercaladas com seu código.

Para obter mais informações sobre os novos aprimoramentos linguagem Visual Basic 2005, visite o seguinte site da Web Microsoft Developer Network (MSDN): Para obter mais informações sobre classes parciais e o Windows Forms Designer, visite o seguinte site da MSDN:
Referências
Para obter mais informações, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
316422Mapa para threading no Visual Basic .NET
Para ver um exemplo multithread Windows Forms controlar, visite o seguinte site da MSDN:

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 318604 - Última Revisão: 05/16/2007 05:35:25 - Revisão: 3.6

Microsoft Visual Basic 2005, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual Basic .NET 2002 Standard Edition, Microsoft ADO.NET 1.0

  • kbmt kbvs2005swept kbvs2005applies kbhowtomaster KB318604 KbMtpt
Comentários