Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Skeletron en 5 Enero 2010, 02:37 am



Título: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 02:37 am
Hola gente..
Les comento que estoy (aun no lo hice) por hacer una aplicacion que tendría que funcionar como BOT INDEXADOR de una web.

La cuestion es que, con vb.net, tengo que descargar el codigo fuente de una web, analizar las etiquetas <img ...> y tomar el link de la imagen.

La cuestion, es que necesito que el programa sea lo mas rapido posible.. y como sabran, el problema principal en velocidad, estará en la velocidad de descarga del archivo...
Tengo una conexión de 1MB solamente, y si descargo un archivo con la aplicacion, estoy toltamente seguro que no utilizaré el 100% del ancho de banda.. entonces se me dió la idea de que tal vez podria mejorar eso, si tengo en todo momento descargando archivos...

Mi idea era crear unos cuantos hilos, supongamos 10.

La idea, es que con un webclient, descargo archivos de manera asincronica, y cuando se termine de descargar el codigo fuente (creo que hay un evento para ello), ejecuto un hilo que lo analiza, y al terminar de analizarlo, o sea, al final del hilo, hago que esa mismo webclient, comience con la descarga del proximo archivo, y repetir ésto..

O sea.. a ver si me explico:
Al darle al boton COMENZAR, se comenzaran a descargar en 10 webclients las webs, y al terminar una, se ejecuta un hilo (thread) y analiza ese codigo, y al terminar de realizar ese analisis, coloca de nuevo a descargar otro archivo al webclient que llamó a éste hilo..

Preguntas:
Ustedes creen que de esa manera ocuparé mejor el tiempo de descarga?
Alguien tiene alguna idea mejor?
Alguien conoce algun metodo rapido, o alguna funcion de .net para analizar etiquetas html en un codigo fuente?


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 02:57 am
Alguno de todos ustedes sabe utilizar éstos metodos:
http://msdn.microsoft.com/es-es/library/system.net.webclient.downloadstringcompleted%28VS.80%29.aspx
http://msdn.microsoft.com/es-es/library/system.net.webclient.ondownloadstringcompleted%28VS.80%29.aspx

Se supone que son los que me avisarán cuando se termine de descargar el codigo en el webclient...


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: seba123neo en 5 Enero 2010, 03:21 am
¿¿ vos descargas la web para analizar el codigo fuente??  :o, se puede directamente sacar los link y cualquier otra cosa que quieras de uan web sin necesidad de estar bajandola.


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: raul338 en 5 Enero 2010, 03:32 am
¿¿ vos descargas la web para analizar el codigo fuente??  :o, se puede directamente sacar los link y cualquier otra cosa que quieras de uan web sin necesidad de estar bajandola.

como? que yo sepa, bajando el html solo xD

Nunca utilizé el WebClient, siempre use el WebRequest y WebResponse, obtienes el HTML en string puro, y de ahi analizas (obtienes las etiquetas "A" si el documento es un xml valido, cosa que muy poco pasa, sino...tratamiento de strings ... o ...Expresiones regulares, mis favoritas :P)


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: seba123neo en 5 Enero 2010, 03:47 am
jaja obvio, claro, cuando dije bajar la "web" me referia al html  :xD, pero lo que no entendi es si ¿estas bajando el html al disco duro como un archivo y despues lo abris y lo recorres para sacar los links?, porque obvio se puede hacerlo "onfly" digamos sin bajar nada al disco.


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 04:25 am
Yo no dije bajar al disco.. Cualquier recurso que pase de internet a una PC, e una BAJADA... se baja a la ram..  :)

O sea.. a una variable..

Dim w1 As New WebClient
Dim U As New Uri("http://www.brodasoft.com.ar/Standart/index.html")
w1.DownloadStringAsync(U)



Como creo un metodo con el handles del "downloadstringcomplete"????
Y en cuanto a lo de expresiones regulares, será algo así lo que tu dices: http://www.elguille.info/regexp/regExp01.aspx ... creo que eso me sará basta para poder encontrar las imagenes dentro de los codigos html :D

Ahora el problema esta en como crear el metodo que controle el evento que se terminó de "bajar" el html al webclient :/


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: seba123neo en 5 Enero 2010, 04:39 am
proba algo asi:

Código
  1. Imports System.Net
  2.  
  3. Public Class Form1
  4.  
  5.    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  6.  
  7.        Dim vCliente As New WebClient
  8.  
  9.        AddHandler vCliente.DownloadStringCompleted, AddressOf DescargaCompleta
  10.  
  11.        Dim vPagina As New Uri("http://www.brodasoft.com.ar/Standart/index.html")
  12.  
  13.        vCliente.DownloadStringAsync(vPagina)
  14.    End Sub
  15.  
  16.    Public Shared Sub DescargaCompleta(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
  17.  
  18.        If e.Cancelled = False AndAlso e.Error Is Nothing Then
  19.            Dim vCodigoFuente As String = CStr(e.Result)
  20.            MessageBox.Show("Descarga Completa")
  21.            MessageBox.Show(vCodigoFuente)
  22.        End If
  23.  
  24.    End Sub
  25. End Class

PD: tambien podes poner un AddHandler a DownloadProgressChangedy ver el progreso de descarga...


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 04:48 am
Genal Sebas.. te lo agradezco una y mil veces..
lo del progreso no será suficiente.. total será en un segundo. muchas gracias!!!


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 05:37 am
EDITO:
Ahora que lo pienso bien.. no voy a tener que Sincronizar nada.. si no usaré hilos de ésta manera... :/

EDITO NUEVAMENTE:
Ahora se me armó un quilombo.. uso o no uso?? voy a hacer unas pruebas...

(ésto que viene aqui debajo, lo habia escrito antes)

Che.. y continuando con el tema de optimizacion...
Yo voy a tener 10 "Dim x as webclient"

Los 10 van a ejecutar el mismo metodo de analisis(al terminar la descarga)... tendria que sincronizar el metodo?? Hay algun identificador para sincronizar un metodo entero? (en java se puede)

Siempre me jodió el tema éste de la sincronizacion de un fragmento de codigo (o sea, no un metodo entero), porque no entiendo porque tengo que poner un objeto en la sentencia SyncLock.. o sea.. si yo tengo varias cosas por sincronizar (todo lo que esté dentro de la lineas de codigo), no tengo porque darle un "synclock" a un solo objeto... que se yo.. no entiendo eso..


En este caso tendría que ser así o no?:
Código
  1. Imports System.Net
  2.  
  3. Public Class Form1
  4.  
  5.    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  6.  
  7.        Dim vCliente As New WebClient
  8.  
  9.        AddHandler vCliente.DownloadStringCompleted, AddressOf DescargaCompleta
  10.  
  11.        Dim vPagina As New Uri("http://www.brodasoft.com.ar/Standart/index.html")
  12.  
  13.        vCliente.DownloadStringAsync(vPagina)
  14.    End Sub
  15.  
  16.    Public Shared Sub DescargaCompleta(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
  17.        Synclock e
  18.        If e.Cancelled = False AndAlso e.Error Is Nothing Then
  19.            Dim vCodigoFuente As String = CStr(e.Result)
  20.            MessageBox.Show("Descarga Completa")
  21.            MessageBox.Show(vCodigoFuente)
  22.        End If
  23.        End Synclock
  24.  
  25.    End Sub
  26. End Class


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 06:14 am
Creo otro post aqui debajo, por si Sebas y demas gente ya pasaron, y no verán el post en "no leidos desde la ultima visita"


Una cagada... todo mal.. tengo que Sincronizar el metodo... y si o si el metodo entero.. porque.. miren.. ise la siguiente prueba:



Código
  1. Imports System.Threading
  2. Imports System.Net
  3.  
  4. Public Class Picdex
  5.  
  6.    Dim _w1 As New WebClient
  7.    Dim _w2 As New WebClient
  8.  
  9.    Private Sub Picdex_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  10.        AddHandler _w1.DownloadStringCompleted, AddressOf Trabajar
  11.        AddHandler _w2.DownloadStringCompleted, AddressOf Trabajar
  12.    End Sub
  13.  
  14.    Private Sub Comenzar(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  15.        _w1.DownloadStringAsync(New Uri("http://www.brodasoft.com.ar/Standart/index.html"))
  16.        _w2.DownloadStringAsync(New Uri("http://www.brodasoft.com.ar/Standart/index.html"))
  17.    End Sub
  18.  
  19.    Private Sub Trabajar(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
  20.        SyncLock e
  21.            MsgBox("Inicio")
  22.            For pepe As Integer = 1 To 300
  23.                Thread.Sleep(1)
  24.            Next
  25.            MsgBox("Fin")
  26.        End SyncLock
  27.    End Sub
  28.  
  29. End Class


Si ejecuto eso, como veran hay un msgbox dentro del Synclock.. pero aparecen los 2 mensajes de "INICIO" seguidos... o sea.. yo tengo que hacer algo para que primero se ejecute todo el metodo, y al terminar el metodo, vuelva a ejecutarse con el 2º webclient que produjo el evento...

Definitivamente tengo que usar hilos???


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: raul338 en 5 Enero 2010, 13:42 pm
Si ejecuto eso, como veran hay un msgbox dentro del Synclock.. pero aparecen los 2 mensajes de "INICIO" seguidos... o sea.. yo tengo que hacer algo para que primero se ejecute todo el metodo, y al terminar el metodo, vuelva a ejecutarse con el 2º webclient que produjo el evento...

Definitivamente tengo que usar hilos???

Pero..... es justamente esa la diferencia entre usar hilos en vez bucles en un solo hilo. O sea, si queres bajar una por una, hacelo en un bucle, si queres hacer "varios" a la vez, usa hilos.

Si queres bajar 10, pero no a la vez, supongamos que 3 a la vez. cuando termine uno empieze el que sigue. Implementa semaforos en los hilos. Aca un ejemplo de un amigo mio:

http://www.xtremecodes.es/downloads.php?cat_id=6 (http://www.xtremecodes.es/downloads.php?cat_id=6) (Nota: Es zona de descarga, descarga el que dice Threads con semaforos y/o tambien Threads)


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 17:10 pm
Descargando... vamos a ver que dice..
Capaz no me vuelva a pasar por aqui por unos dias, por cuestiones de vacaciones.. pero volveré :D


Título: Re: Necesito optimizar una aplicacion!!!
Publicado por: Skeletron en 5 Enero 2010, 20:02 pm
Creo que despues de años, encontre hacer lo que busco :D

Miren lo que tengo:

Código
  1. Imports System.Threading
  2. Imports System.Net
  3.  
  4. Public Class Picdex
  5.  
  6. #Region "WebClients"
  7.    Dim _w1 As New WebClient
  8.    Dim _w2 As New WebClient
  9.  
  10.    Dim _hilo1 As Thread = New Thread(AddressOf TrabajoW1)
  11.    Dim _hilo2 As Thread = New Thread(AddressOf TrabajoW2)
  12. #End Region
  13.  
  14.        Private Sub Picdex_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  15.        AddHandler _w1.DownloadStringCompleted, AddressOf _hilo1.Start
  16.        AddHandler _w2.DownloadStringCompleted, AddressOf _hilo2.Start
  17.    End Sub
  18.  
  19.    Private Sub Comenzar(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  20.        _w1.DownloadStringAsync(New Uri("http://www.brodasoft.com.ar/Standart/index.html"))
  21.        _w2.DownloadStringAsync(New Uri("http://www.brodasoft.com.ar/Standart/VIDay.html"))
  22.    End Sub
  23.  
  24. #Region "Trabajos de W1"
  25.    Private Sub TrabajoW1()
  26.        MsgBox("TrabajoW1 Listo")
  27.        MsgBox("TrabajoW1 Fin")
  28.    End Sub
  29.  
  30.    Private Sub TrabajoW2()
  31.        MsgBox("TrabajoW2 Listo")
  32.        MsgBox("TrabajoW2 Fin")
  33.    End Sub
  34.  
  35. #End Region
  36.  
  37. End Class
  38.  

Se supone que este codigo le dará START al hilo correspondiente al webclient...
El problema, obviamente, es que no ahorro codigo.. porque tengo 1 metodo por cada hilo.. pero yo busco multiprocesamiento simetrico y descargas paralelas.. nada mas...

Pensé en hacer algo así yo:
crear los 2 webclients, y ejecutar siempre el mismo metodo creando un hilo por cada evento que se produzco y darle por parametro el webclient que produjo el evento.. pero.. para ésto, tendria que hacer algo así:
AddHandler _w1.DownloadStringCompleted, AddressOf (y aqui crear un hilo nuevo y mandar por parametros (_w1))

Pero.. en el addessOf no se pueden poner parametros.. :/
O sea.. no encuentro manera de ejecutar un hilo al producirce un evento, y que éste hilo tenga por parametros el webclient que se ejecutó.. No encuentro manera de establecer una buena sincronizacion..
Porque si hago:
AddHandler _w1.DownloadStringCompleted, AddressOf METODOX
y METODOX es un metodo que crea un hilo que manda por parametros a _w1..
Si 2 eventos se producen casi en el mismo instante.. no alcanza a crear el hilo el 1º evento que se produjo, porque el 2º es como si lo ELIMINARA.. como si cortara automaticamente el 1º evento antes de terminar su operacion de crear el 1º hilo