Aplicacion de descarga se pinza

Iniciado por Kaxperday, 18 Noviembre 2014, 18:37 PM

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

Kaxperday

Hola tengo una aplicación en C# y hace webscraping a un gran numero de foros, el problema es que cuando trabaja la aplicación se bloquea dice que no responde así hasta que acaba de decargar todo, y puede llegar a 10 minutos o mucho más si hay muchos foros a webscrapear.

He probado a ponerle Thread.Sleep(10); pero nada sigue igual.

También he de destacar que a medida que lo descarga lo muestra en una textbox cosa que no ocurre porque se queda sin responder y cuando acaba muestra los foros descargados en la textbox y todo va bien, pero hasta entonces el programa pinzado, bloqueado...

¿Puedo evitar eso?

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

engel lex

no se si esto te sirva... en mis antiguos tiempos de vb6 para evitar eso estaba el comando doevents

http://support.microsoft.com/kb/118468/es

por lo que entiendo lo que hace es que le pasa la batuta al SO para que procese los eventos relacionados al programa y despues continua su proceso normal... no se si se aplica en .net
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Kaxperday

Mil gracias compañero me funcionó perfectamente :))) jajaja

https://social.msdn.microsoft.com/Forums/en-US/27930e10-c01b-49b8-8d8f-5922d2a5e426/c-equivalency-of-vb-function-doevents?forum=Vsexpressvcs

Código para C#:

Application.DoEvents();

Lo metes dentro del bucle y solucionado jaja, aunque va un poco lagueado xDD pero va dpm

Gracias.

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Eleкtro

#3
Cita de: Kaxperday en 18 Noviembre 2014, 18:55 PMApplication.DoEvents();

En vb6 vale, pero hay mitos y leyendas sobre la instrucción "DoEvents" en .Net, es una solución al problema que tienes pero que acarraerá otro tipo de problemas en segundo plano... por ejemplo el "lag" al que te refieres ya que la instrucción "DoEvents" se procesa cada cierto tiempo dentro del búcle que hiciste, no es nada recomendable usar esa "técnica" ni siquiera como último recurso, más cuando tienes una multitud de alternativas que son las que debes utilizar.

Lo que te ocurre con la aplicación es lo más normal del mundo ya que es single-thread. La duda que tienes es debido a una falta de conocimientos y entendimiento sobre lo que estás haciendo, sobre un concepto muy importante de la proramación;
Debes aprender programación asíncrona, el uso del multi-threading:

BackgroundWorker Class (System.ComponentModel)
Thread Class (System.Threading) - MSDN
Task Class (System.Threading.Tasks) - MSDN


Cita de: Kaxperday en 18 Noviembre 2014, 18:37 PMHe probado a ponerle Thread.Sleep(10); pero nada sigue igual.

Esa instrucción precisamente debes evitar usarla, ya que sirve para detener la ejecución del thread actual... (es decir para "colgar" la app y dejarla sin respuesta)

En otras palabras, las tareas "intensivas" debes realizarlas en segundo plano (sub-threads) sí o sí para no colapsar/colgar el thread actual, no utilices DoEvents.

Saludos








Kaxperday

Gracias por la respuesta elektro lo tendré en cuenta la verdad que con el doenvents se pinza tambien, pasado un rato se pinza, tendré que aprender a usar eso de threads, aunque cuantos deberái crear?

Solo un proceso hijo para que haga la descarga bastaría no? y no se pinzaría verdad?

O necesito varios, ¿qué garantías me dan los threads y cuantos he de usar?

Gracias.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Eleкtro

#5
Cita de: Kaxperday en 19 Noviembre 2014, 22:49 PM
Gracias por la respuesta elektro lo tendré en cuenta la verdad que con el doenvents se pinza tambien, pasado un rato se pinza, tendré que aprender a usar eso de threads, aunque cuantos deberái crear?

Solo un proceso hijo para que haga la descarga bastaría no? y no se pinzaría verdad?

O necesito varios, ¿qué garantías me dan los threads y cuantos he de usar?

Gracias.

No he visto el código que tienes y dependiendo de la situación/código recomiendo una cosa u otra, pero me hago una idea que debe ser un código bastante "tocho" donde haces peticiones a webs y procesas los source y tal así que creo que lo mejor en tu caso sería que arrastrases al Form un BackgroundWorker (solo uno) y utilices sus eventos para realizar la tarea del Web-Spider en segundo plano, tanto acceder a webs como la descarga.

Formas hay muchas, y te sirve por igual un Thread, Task, o BackgroundWorker, pero veo mucho más apto el BakgroundWorker en tu caso por que debes ir actualizando el estado de las descargas y tal en la UI (o eso pre-supongo sin haber visto el code), y el BakgroundWorkers te facilida esa tarea de "actualización" gracias a los eventos que dispone a los que puedes suscribirte.

¿Garantías?, lo que ocurra en segundo plano se queda en ese segundo plano, quiero decir que la UI (que es el thread principal) no se va a colapsar/colgar/laguear en ningún momento si elaboras bien el código, es decir, sin usar el For en el thread de la UI por que eso es lo que genera el colapso, lo que tengas que hacer hazlo en segundo plano.

Te sugiero leer ejemplos donde usen BakgroundWorkers para aprender su funcionamiento y no cometer errores, ya que no es cosa de 1 día y quizás no te salga como esperas a la primera:
http://lmgtfy.com/?q=codeproject+backgroundworker

PD: Y si estás usando .Net Framework 4.5 te puedes servir también de las "nuevas" declaraciones asíncronas:
Asynchronous Programming with Async and Await

Saludos!








Kaxperday

Hola elektro siento no haber respondido antes, muchas gracias por tu respuesta lo primero.

La verdad me alegre y no al ver tu mensaje xD, poruqe hay una opción para solucionarlo y otra que tengo que aprendermela para saber hacerlo xD.

Vale, entonces como debería de hacer para hacerlo con threads?, estoy trabajando con C#, que debería de crear una clase en el form que al pulsar el boton de descargar se inicia un proceso hijo y descarga pero que pasa con lo demás?, muy lioso, miré tus links de clases y demás pero ni idea de implementarlo xD.

Saludos socio.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Kaxperday

Ya lo solucione resulto sencillo después de todo:

Código (csharp) [Seleccionar]
private void botonForos_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(descargaForos));
            thread.Start();
        }


Y puedes poner una variable privada en el form un booleano, pones un boton que diga "detener descarga" y cambia el valor del boleano, entonces en descargaForos en el bucle, hace una comprobación del booleano si es true se detiene y sale del bucle, asi de simple.

Gracias por guiarme un poco.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Eleкtro

#8
Cita de: Kaxperday en 22 Noviembre 2014, 20:57 PMVale, entonces como debería de hacer para hacerlo con threads?, estoy trabajando con C#, que debería de crear una clase en el form que al pulsar el boton de descargar se inicia un proceso hijo y descarga pero que pasa con lo demás?, muy lioso, miré tus links de clases y demás pero ni idea de implementarlo xD.

Bueno, es que eso sinceramente es de cosecha propia... el código hay que elaborarlo según las circunstancias, me limité a darte la información necesaria, no a hacerte el código, pero si te quedas atascado en alguna parte dilo y te ayudare(mos).

De todas formas aquí publiqué un ejemplo de uso genérico de un BGW:
¿Hacer una pausa a un BackgrounWorker en VB.NET?

Ya veo que lo has solucionado con la class Thread, pero bueno, igual te sirve eso. además, ten en cuenta que Microsoft considera obsoletos los métodos de pausa de la class Thread (Suspend, Resume)

saludos