Siempre he hecho aplicaciones en .net descargando archivos pero ahora necesito si o si que no se me frize el form mientras se descarga algo.
Normalmente cuando ejecutas request.GetResponse() en un objeto WebRequest el form se congela y cuando finaliza la respuesta del servidor ahi recién se descongela.
Recuerdo hace años que en vb6 eso no pasaba, uno porque usabas control de usuarios para los sockets y todo era con subs en hilos de proceso y con inet tampoco se frizaba el form, simplemente la función no continuaba pero no comprometía el form.
Como lo hago en .net?
Por ahora hize un pequeño código:
Imports System.IO
Imports System.Net
Public Class Form1
Private Sub SalirToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SalirToolStripMenuItem.Click
End
End Sub
Private Sub ConectarToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConectarToolStripMenuItem.Click
Timer1.Enabled = True
Timer1.Start()
End Sub
Private Sub Process_data(ByVal Data As String)
' Constructor...
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Estado.Text = "Conectando ..."
Application.DoEvents()
' Create a request for the URL.
Dim request As WebRequest = WebRequest.Create("http://wordpress.org/latest.zip")
' If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials
' Get the response.
Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
' Display the status.
Console.WriteLine(response.StatusDescription)
' Get the stream containing content returned by the server.
Dim dataStream As Stream = response.GetResponseStream()
' Open the stream using a StreamReader for easy access.
Dim reader As New StreamReader(dataStream)
' Read the content.
Dim responseFromServer As String = reader.ReadToEnd()
' Display the content.
Dim Content As String = responseFromServer
' Cleanup the streams and the response.
reader.Close()
dataStream.Close()
response.Close()
Process_data(Content)
Estado.Text = "Datos obtenidos"
End Sub
Private Sub DesconectarToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DesconectarToolStripMenuItem.Click
Timer1.Enabled = False
Timer1.Stop()
End Sub
End Class
Realmente puse ese zip como ejemplo pero en la práctica será un chat y no quiero que rapte el form mientras descarga las actualizaciones cada 4 segundos de un xml.
También intenté con
Response.GetResponseStream().Read(...
Me puse a leer de a 1024 bytes con un application.doevents() pero aun asi, igual se friza el form mientras hace las consultas.
Si lo único que necesitas hacer es eso, lo más sencillo es utilizar un Thread para lanzar el proceso de descarga en background.
Ahora, si lo quieres hacer del modo "correcto" y mostrar entre otras cosas el estado de la descarga, lo mejor es utilizar el método BeginGetResponse y el objeto IAsyncResult
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx
Saludos
la respuesta de novlucker es buena! sino puedes cambiar por hacerlo con WebClient y de manera asincronica, asi no se te frisara el form ni nada y tiene varios eventos los cuales puedes usar para obtener la descarga y para el porcentaje! suerte