elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [Duda] Aplicacion queda congelada
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Duda] Aplicacion queda congelada  (Leído 3,316 veces)
OscarCadenas_91

Desconectado Desconectado

Mensajes: 27


Ver Perfil
[Duda] Aplicacion queda congelada
« en: 17 Octubre 2015, 09:36 am »

Buenas a todos, tengo una  duda, haber si alguien me puede orientar.

Estoy creando un aplicacion que busca palabras en un archivo de texto
Código
  1.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  2.        Dim nCoincidencias As Integer = 0
  3.        Dim texto As String = IO.File.ReadAllText("D:\resumen.txt")
  4.        If texto.Contains("Solucion") Then
  5.            nCoincidencias = nCoincidencias + 1
  6.        End If
  7.        If texto.Contains("Libro") Then
  8.            nCoincidencias = nCoincidencias + 1
  9.        End If
  10.        If texto.Contains("Autor") Then
  11.            nCoincidencias = nCoincidencias + 1
  12.        End If
  13.    End Sub
  14.  

El problema viene cuando intento usar archivo un poco mas grande la aplicacion se queda congelada, sin poder hacer nada.


Busque informacion y lo que encontre es que se puede usar: Backgroundworker y usando Threads
Me podrian decir cual es la diferencia entre ambos, y que puedo mejorar en el codigo para no usar muchos IF



gracias


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: [Duda] Aplicacion queda congelada
« Respuesta #1 en: 17 Octubre 2015, 15:26 pm »

Estoy creando un aplicacion que busca palabras en un archivo de texto

El problema viene cuando intento usar archivo un poco mas grande la aplicacion se queda congelada, sin poder hacer nada.

Para solucionarlo simplemmente ejecuta las órdenes de manera asíncrona en el mismo thread de la UI, o en un thread separado.

Este ejemplo toma un archivo de texto de 300 MB, busca 3 palabras y muestra la suma de coincidencias de las palabras encontradas.



Código
  1. Imports System.Threading.Tasks
  2.  
  3. Public NotInheritable Class Form1 : Inherits Form
  4.  
  5.    Private Sub Button1_Click(sender As Object, e As EventArgs) _
  6.    Handles Button1.Click
  7.  
  8.        Dim ocurrences As Integer = -1
  9.  
  10.        Task.Factory.StartNew(Sub() Me.Find("C:\resumen.txt", {"Solucion", "Libro", "Autor"}, ocurrences)).
  11.                 ContinueWith(Sub()
  12.                                  Me.Invoke(Sub()
  13.                                                TextBox1.Text = String.Format("Coincidencias: {0}", CStr(ocurrences))
  14.                                                Label1.Text = "Operación completada!"
  15.                                            End Sub)
  16.                              End Sub)
  17.  
  18.        Dim sw As New Stopwatch
  19.        sw.Start()
  20.        Do Until (ocurrences <> -1)
  21.            Label1.Text = String.Format("{0} segundos...", sw.Elapsed.TotalSeconds.ToString("n2"))
  22.            Application.DoEvents()
  23.        Loop
  24.        sw.Reset()
  25.  
  26.    End Sub
  27.  
  28.    Private Sub Find(ByVal textFilepath As String,
  29.                     ByVal values As IEnumerable(Of String),
  30.                     ByRef var As Integer)
  31.  
  32.        Using sr As New StreamReader(textFilepath, True)
  33.  
  34.            var = (From word As String In (sr.ReadToEnd.Split).AsParallel
  35.                   Select (From value As String In values
  36.                           Where word.Equals(value, StringComparison.OrdinalIgnoreCase)).Count
  37.                  ).Sum
  38.  
  39.        End Using
  40.  
  41.    End Sub
  42.  
  43. End Class

El contador de segundos lo he colocado solo para que denotes que no se congela la UI, pero en realidad eso vuelve (algo)más lento el procedimiento xD.

He usado LINQ por su intuitiva y simplificada sintaxis, pero si quieres mayor optimización en respecto al rendimiento entonces usa un For. Aquí tienes varios ejemplos en C#:

C# .Net: Fastest Way to check if a string occurs within a string



Backgroundworker y Threads
Me podrian decir cual es la diferencia entre ambos



_____________________________________________________________________
EDITO: Ups, he ido a revisar mi comentario y no se por qué leí que preguntabas sobre "Tasks" en lugar de "Threads", me he dado cuenta tarde así que todo esto que comento aquí abajo es sobre la class Task y no sobre theads o hilos en general, pero de todas formas es lo que deberías utilizar, una Task.

Sobre las diferencias, la class Threading.Thread es el concepto o implementación low-level de un hilo, mientras que la class Threading.Thread sería un nivel superior de su implementación, ya que tiene mayor abstracción.

La class Threading.Task representa una operación asíncrona que es llevada acabo mediente hilos, los cuales son administrados mediante su propio planificador de hilos o thread scheduler.

No te conviene usar hilos tradicionales mediante Threading.Thread ya que está pensado para otros escenarios donde se requiere un mayor requisito de computación, es preferible que uses la class Threading.Task.
_____________________________________________________________________




La diferencia más grande tal vez está en su modo de empleo, ya que la class Task es la evolución de la class BackgroundWorker.

Existen muchas diferencias internas entre si en el contexto de como administra los hilos, su cancelación, la sincronia de código, etc. Para destacar todo ello habría que escribir un libro, así que si quieres aprender en profundidad sobre sus diferencias es mejor que busques en Google artículos que hablen sobre ello, pero en resumen el BackgroundWorker o BGW tiene varios problemas de diseño, y de por si es muy tedioso utilizarlo al estar basado u orientado en eventos; también tiene problemas de sincronización y de tokens de cancelación. Con el paso de los años es posible que Microsoft marque "deprecada" dicha class.

Te muestro una simple comparación de uso:

BGW:
Código
  1. Dim WithEvents bgw As New BackgroundWorker
  2.  
  3. Private Sub Bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
  4. Handles bgw.DoWork
  5.  
  6.    Thread.Sleep(1000)
  7.  
  8. End Sub
  9.  
  10. Private Sub Bgw_RunWorkerCompleted(ByVal sender As Object,ByVal e As RunWorkerCompletedEventArgs) _
  11. Handles bgw.RunWorkerCompleted
  12.  
  13.    MessageBox.Show("Operation completed!")
  14.  
  15. End Sub
  16.  
  17.  
  18. Private Sub RunBgw()
  19.  
  20.    Me.bgw.RunWorkerAsync()
  21.  
  22. End Sub

BGW simplificado:
Código
  1. Sub ...
  2.  
  3. Using bgw As New BackgroundWorker
  4.  
  5.    AddHandler bgw.DoWork, Sub()
  6.                               Thread.Sleep(1000)
  7.                           End Sub
  8.  
  9.    AddHandler bgw.RunWorkerCompleted, Sub()
  10.                                           MessageBox.Show("Operation completed!")
  11.                                       End Sub
  12.    bgw.RunWorkerAsync()
  13.  
  14. End Using
  15.  
  16. End sub

Task.Run:
Código
  1. Async Sub ...
  2.  
  3.    Await Task.Run(Sub()
  4.                       Thread.Sleep(1000)
  5.                   End Sub)
  6.  
  7.    MessageBox.Show("Operation completed!")
  8.  
  9. End sub

Nota: Async/Await forman parte de .NetFx 4.5

Saludos!


« Última modificación: 17 Octubre 2015, 16:53 pm por Eleкtro » En línea



OscarCadenas_91

Desconectado Desconectado

Mensajes: 27


Ver Perfil
Re: [Duda] Aplicacion queda congelada
« Respuesta #2 en: 18 Octubre 2015, 15:24 pm »

Muchas Gracias por responder elektro.
Me ha servido de mucho y funciona perfectamente, hace tiempo no sabia como era LINQ, ahora ya puedo entenderlo gracias a tus ejemplos que publicas, solo me queda aprender a crearlas.
Y tambien revisando tus codigos de ejemplo sobre como usar Task, ya lo comprendi casi todo, gracias por todo.
En línea

[D4N93R]
Wiki

Desconectado Desconectado

Mensajes: 1.646


My software never has bugs. Its just features!


Ver Perfil WWW
Re: [Duda] Aplicacion queda congelada
« Respuesta #3 en: 23 Octubre 2015, 17:32 pm »

Buenas,

Recomendaría usar Threads hasta que tengas el tema dominado y luego saltar a clases de nivel superior. Primero low level y luego high C:

Así cuando uses Tasks, o cualquier otra abstracción de otro proceso, sepas lo que se está haciendo por debajo de todas esas clases. OJO, no digo que por ejmplo un mecánido deba saber las ecuaciones de termodinámica que se aplican en un motor en el momento de la combustión, pero si me gustaría que si mi mecánico me hace un cambio de filtro, sepa al menos que hace el filtro.

Un saludo!!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines