Autor Tema: Ejecutar Consulta sql en segundo plano  (Leído 9766 veces)

0 Usuarios y 1 Visitante están viendo este tema.

javierjava

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +6/-0
    • Ver Perfil
Ejecutar Consulta sql en segundo plano
« en: Octubre 25, 2013, 06:54:22 pm »
Que tal espero que alguien me pueda ayudar, estoy ejecutando un procedimiento almacenado  es muy lento y se tarda como 10 minutos para traer los datos el problema es que el formulario ya no responde hasta que el proceso se termine de ejecutar mi pregunta es si hay alguna forma de que el formulario no cuelgue estoy usando el siguiente código.

Código: [Seleccionar]
        Dim args As String = "Data Source=server;Initial Catalog=base;Integrated Security=True"


        Using connection As SqlConnection = New SqlConnection(args)
            Dim Command As SqlCommand
            Dim Adapter As SqlDataAdapter
            Dim DtTable As DataTable

            Command = New SqlCommand("", connection)
            Command.CommandType = CommandType.StoredProcedure
            Command.CommandTimeout = 5 * 600

            Adapter = New SqlDataAdapter(Command)
            DtTable = New DataTable

            With Command.Parameters
                .Add(New SqlParameter("@A", SqlDbType.DateTime)).Value = ""

                .Add(New SqlParameter("@T", SqlDbType.VarChar)).Value = ""

            End With
            Try
                Adapter.Fill(DtTable)
                DataGridView1.DataSource = DtTable
                DataGridView1.AutoGenerateColumns = False
                With DataGridView1

                End With
            Catch expSQL As SqlException
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
                Exit Sub
            End Try
        End Using

 espero que alguien me pueda ayudar gracias.
« última modificación: Noviembre 05, 2013, 03:27:54 pm por javierjava »

seba123neo

  • Moderador
  • Terabyte
  • *****
  • Mensajes: 763
  • Reputación: +88/-5
    • Ver Perfil
Re:Ejecutar Consulta sql en segundo plano
« Respuesta #1 en: Octubre 25, 2013, 07:19:37 pm »
mete ese proceso dentro de un thread y listo, pero 10 minutos es una locura, ¿ tantos datos hay ? creo que faltan indices.

con indices bien puestos, podes bajar consultas de minutos a 1 segundo.

saludos.

wolf_kof

  • Visitante
Re:Ejecutar Consulta sql en segundo plano
« Respuesta #2 en: Octubre 26, 2013, 02:06:26 pm »
Lo que necesitas es hacerlo asíncrono pero seba tiene razón 10 minutos es mucho...

Aqui un link donde te explica como debes crear el método asíncrono.

http://msdn.microsoft.com/es-es/library/e7a34yad.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

javierjava

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +6/-0
    • Ver Perfil
Re:Ejecutar Consulta sql en segundo plano
« Respuesta #3 en: Octubre 28, 2013, 10:49:29 am »
Gracias por responder seba123neo, ya lo meti  dentro de un thread y me da el siguiente error Operación no válida a través de subprocesos: Se tuvo acceso al control 'DataGridView1' desde un subproceso distinto a aquel en que lo creó.



Código: [Seleccionar]
[code] Private trd As Thread[/code]
Código: [Seleccionar]
Imports System.Threading
Código: [Seleccionar]
Private Sub Tarea()
        Dim args As String = "Data Source=servidor;Initial Catalog=base;Integrated Security=True"
        Using connection As SqlConnection = New SqlConnection(args)
            Dim Command As SqlCommand
            Dim Adapter As SqlDataAdapter
            Dim DtTable As DataTable

            Command = New SqlCommand("CARTERA", connection)
            Command.CommandType = CommandType.StoredProcedure
            Command.CommandTimeout = 5 * 600

            Adapter = New SqlDataAdapter(Command)
            DtTable = New DataTable

            With Command.Parameters
                .Add(New SqlParameter("@CIERRE", SqlDbType.DateTime)).Value = "#31/05/2013#"

                .Add(New SqlParameter("@TIPOREPORTE", SqlDbType.VarChar)).Value = "S"
            End With
            Try
                Adapter.Fill(DtTable)
                DataGridView1.DataSource = DtTable
                DataGridView1.AutoGenerateColumns = False
                With DataGridView1

                End With
            Catch expSQL As SqlException
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
                Exit Sub
            End Try
        End Using
    End Sub


Código: [Seleccionar]
trd = New Thread(AddressOf Tarea)
        trd.IsBackground = True
        trd.Start()



wolf_kof gracias por responder el problema esque el programa ya esta echa solo estoy modificando algunas cositas y cambiar todo lo que tiene pues es mucho.


seba123neo

  • Moderador
  • Terabyte
  • *****
  • Mensajes: 763
  • Reputación: +88/-5
    • Ver Perfil
Re:Ejecutar Consulta sql en segundo plano
« Respuesta #4 en: Octubre 28, 2013, 08:22:55 pm »
ese es el error basico de los threads, no podes manipular un control de la interfaz grafica, ya que corre en un thread diferente al que vos estas ejecutando ahi.

la solucion a eso es usar delegados, por ejemplo:

Código: (VB) [Seleccionar]
    Imports System.Threading
     
    Public Class Form1
     
       Private Delegate Sub Progreso()
       Private vHilo As Thread
     
       Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     
           TextBox1.Text = 0
     
           vHilo = New Thread(New ThreadStart(AddressOf Proceso))
           vHilo.Start()
       End Sub
     
       Private Sub Proceso()
           If Me.InvokeRequired Then
               Me.Invoke(New Progreso(AddressOf Proceso))
           Else
               Do While True
                   TextBox1.Text += CInt(1)
                   Application.DoEvents()
               Loop
           End If
       End Sub
    End Class

lo que hace es simplemente sumar un valor en el textbox en un bucle infinito, que sin el thread se te trabaria toda la pantalla y no podrias tocar nada, y como usa el control textbox hay que usar un delgado, de lo contrario te sale el famoso error "Operación no válida a través de subprocesos: Se tuvo acceso al control 'TextBox1' desde un subproceso distinto a aquel en que lo creó.", ese error quiere decir que no podes manipular un control del formulario, ya que este esta en un hilo diferente (el hilo de la UI), que es diferente al hilo que creas vos ahi.

la otra forma es ignorar el error con poner en el Load del formulario la siguiente linea:

Código: (VB) [Seleccionar]
CheckForIllegalCrossThreadCalls = True
pero eso lo ignora y no es recomendable hacerlo, podes tener "crash" del programa inadvertidos.

saludos.

javierjava

  • Kilobyte
  • **
  • Mensajes: 69
  • Reputación: +6/-0
    • Ver Perfil
Re:Ejecutar Consulta sql en segundo plano
« Respuesta #5 en: Octubre 30, 2013, 04:54:24 pm »
 seba123neo Disculpa la ignorancia entonces Mi código quedaría algo asi?

Código: [Seleccionar]
Private Sub Proceso()
           If Me.InvokeRequired Then
               Me.Invoke(New Progreso(AddressOf Proceso))
           Else
             
               Dim args As String = "Data Source=servidor;Initial Catalog=base;Integrated Security=True"
        Using connection As SqlConnection = New SqlConnection(args)
            Dim Command As SqlCommand
            Dim Adapter As SqlDataAdapter
            Dim DtTable As DataTable

            Command = New SqlCommand("CARTERA", connection)
            Command.CommandType = CommandType.StoredProcedure
            Command.CommandTimeout = 5 * 600

            Adapter = New SqlDataAdapter(Command)
            DtTable = New DataTable

            With Command.Parameters
                .Add(New SqlParameter("@CIERRE", SqlDbType.DateTime)).Value = "#31/05/2013#"

                .Add(New SqlParameter("@TIPOREPORTE", SqlDbType.VarChar)).Value = "S"
            End With
            Try
                Adapter.Fill(DtTable)
               Aquí iría una variable para luego pasarlo al datagrid ? DataGridView1.DataSource = DtTable
                DataGridView1.AutoGenerateColumns = False
                With DataGridView1

                End With
            Catch expSQL As SqlException
                MsgBox(expSQL.ToString, MsgBoxStyle.OkOnly, "SQL Exception")
                Exit Sub
            End Try
        End Using   
               
             
           End If
       End Sub