Título: [SOLUCIONADO] Mi app tarda demasiado en iniciar
Publicado por: Eleкtro en 4 Enero 2013, 11:53 am
Hola, necesito ayuda con mi programa que tarda unos 10 seg. en visualizarse el form principal, y se carga antes el notifyicon que el form con unos segundos de diferencia xD ¿Eso es normal? Antes tardaba incluso más en cargar, pero he mejorado el tiempo de carga ejecutando el sub importante un nuevo thread. En el form load solo hago 4 estúpidas compbocaciones y lo importante corre en un thread separado, por eso pienso que no debería tardar tanto en mostrarse el form... ¿Que puede ser?, ¿Ven algo extraño en el form load? Bueno, voy a intentar dar datos útiles: (http://img853.imageshack.us/img853/7922/captura1wu.png) Proyecto: Windows form Form: double buffered Framework: 4.0 Controles de terceros: un GroupPanel con degradado, un dialogo de carpetas, y una barra de progreso. (La barra de progreso está visible por defecto.) Recursos que tiene que cargar el exe: 3 dll's que pesan en total 5 MB. están separados, aunque también comparé la velocidad unificandolo con .NET shrink y el resultado es el mismo. Prefetch de windows: Desactivado (No pienso activarlo para solucionar el problema) El proyecto entero: http://www.mediafire.com/?zije2zggdmv669t Como podeis ver, es una app sencilla, pero aparte de que tarda en iniciarse, me consumía muchos muchos recursos, si no le libero memória como hago en el form antes consumía 40 mb después de iniciarse SIN TOCAR NADA, ni con dispose lo arreglaba, ahora solo consume 4-5 mb, pero digo que eso es extraño... El form principal: Public Class Form1 #Region "Declarations" Dim filesystem As Object Dim ThisDir As Object Dim mcheck(0) As CheckBox Dim labelnum = 0 Public Shared playerargs As String Public Shared Temp_file As String = System.IO.Path.GetTempPath & "\PlayDir_tmp.m3u" ' Checkboxes Thread Public checkboxes_thread As System.Threading.Thread = New Threading.Thread(AddressOf updatecheckboxes) ' Select all Thread Public select_all_thread As System.Threading.Thread = New Threading.Thread(AddressOf Select_or_unselect_all) ' Randomize thread Public Thread_is_completed As Boolean = False Public Want_to_abort_thread As Boolean = False Public Want_to_cancel_thread As Boolean = False ' Flush memory Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer #End Region #Region "Properties" 'userSelectedPlayerFilePath Public Property userSelectedPlayerFilePath() As String Get Return Textbox_Player.Text End Get Set(value As String) Textbox_Player.Text = value End Set End Property ' userSelectedFolderPath Public Property userSelectedFolderPath() As String Get Return Textbox_Folder.Text End Get Set(value As String) Textbox_Folder.Text = value End Set End Property #End Region #Region "Load / Close" ' Form load Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load If Not My.Computer.FileSystem.DirectoryExists(My.Settings.folderpath) Then My.Settings.folderpath = Nothing ProgressBar.Visible = False Me.Size = New System.Drawing.Size(Me.Width, 240) Panel_Folders.Size = New System.Drawing.Size(0, 0) Checkbox_SelectAll.Enabled = False Else Checkbox_SelectAll.Enabled = True Textbox_Folder.Text = My.Settings.folderpath ProgressBar.Visible = True End If If Not My.Computer.FileSystem.FileExists(My.Settings.playerpath) Then My.Settings.playerpath = Nothing Else Textbox_Player.Text = My.Settings.playerpath End If If My.Settings.randomize = True Then Checkbox_Randomize.Checked = True If My.Settings.autoclose = True Then Checkbox_AutoClose.Checked = True Updatecheckboxes_Start() My.Settings.Save() End Sub ' Form close Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Want_to_abort_thread = True SyncLock thread_1 'ensures all other threads running stop thread_1.Abort() End SyncLock If Not My.Settings.folderpath = Nothing Then GenerarPropiedades() End If My.Settings.Save() NotifyIcon1.Visible = False NotifyIcon1.Dispose() End Sub #End Region #Region "Save / Get settings" ' Generate properties Public Sub GenerarPropiedades() Dim mCheckados(0) As Int32 Dim Cuantos As Int32 = 0 Dim empty = Nothing Try For Each c As CheckBox In Panel_Folders.Controls empty = False Next If Not empty = False Then My.Settings.Valores = Nothing Else For i As Int32 = 0 To mcheck.Length - 1 If mcheck(i).Checked = True Then Cuantos += 1 Array.Resize(mCheckados, Cuantos) mCheckados(Cuantos - 1) = i + 1 End If Next My.Settings.Valores = mCheckados End If Catch End Try End Sub ' Load properties Public Sub CargarPropiedades() If My.Settings.Valores IsNot Nothing Then For Each indiceCheckado As Int32 In My.Settings.Valores() If Not indiceCheckado = 0 Then InvokeControl(mcheck(indiceCheckado - 1), Sub(x) x.Checked = True) End If Next End If End Sub #End Region #Region "Checkboxes" ' Checkbox thread start Private Sub Updatecheckboxes_Start() checkboxes_thread.Abort() checkboxes_thread = New Threading.Thread(AddressOf updatecheckboxes) checkboxes_thread.IsBackground = False checkboxes_thread.Start() End Sub ' Checkbox thread Public Sub updatecheckboxes() If Not My.Settings.folderpath Is Nothing Then InvokeControl(Checkbox_SelectAll, Sub(x) x.Enabled = False) InvokeControl(Checkbox_SelectAll, Sub(x) x.Checked = False) InvokeControl(Button_PLAY, Sub(x) x.Enabled = False) InvokeControl(Button_PLAY, Sub(x) x.BackColor = Color.FromArgb(50, 50, 50)) InvokeControl(Panel_Folders, Sub(x) x.Enabled = False) InvokeControl(ProgressBar, Sub(x) x.TextFormat = "Sorting folders, please wait...") InvokeControl(ProgressBar, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString) ' delete the old checkboxes InvokeControl(Panel_Folders, Sub(x) x.Controls.Clear()) ' create the new checkboxes Dim filesystem = CreateObject("Scripting.FileSystemObject") Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath) Dim i As Int32 = 0 Dim pos As Int32 = 5 For Each folder In ThisDir. Subfolders Array.Resize(mcheck, i + 1) mcheck(i) = New CheckBox With mcheck(i) .BackColor = Color.Transparent .ForeColor = Color.White .AutoSize = False .Size = New Point(338, 20) .Location = New Point(1, pos) .Name = "CheckBox" & i + 1 .Cursor = Cursors.Hand End With InvokeControl(Panel_Folders, Sub(x) x.Controls.Add(mcheck(i))) AddHandler mcheck(i).CheckedChanged, AddressOf LlamadaCheckBox i += 1 pos += 20 Next ' Load checked checkboxes CargarPropiedades() ' Reset saved checked checkboxes My.Settings.Valores = Nothing InvokeControl(ProgressBar, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.None) InvokeControl(ProgressBar, Sub(x) x.TextFormat = "Sorting files... {1}% Done") InvokeControl(Panel_Folders, Sub(x) x.Enabled = True) InvokeControl(Button_PLAY, Sub(x) x.Enabled = True) InvokeControl(Button_PLAY, Sub(x) x.BackColor = Color.SteelBlue) InvokeControl(Checkbox_SelectAll, Sub(x) x.Enabled = True) InvokeControl(Panel_Folders, Sub(x) x.Focus()) End If FlushMemory("PlayDir") End Sub ' Checkbox events Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs) Dim filesystem = CreateObject("Scripting.FileSystemObject") Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath) Dim CheckboxN As CheckBox = CType(sender, CheckBox) If CheckboxN.Checked = True Then labelnum += 1 playerargs = playerargs & " " & ControlChars.Quote & System.IO.Path.Combine(ThisDir.Path, CheckboxN.Text.ToString()) & ControlChars.Quote Else labelnum -= 1 playerargs = Replace(playerargs, " " & ControlChars.Quote & System.IO.Path.Combine(ThisDir.Path, CheckboxN.Text.ToString()) & ControlChars.Quote, "") End If If labelnum < 0 Then labelnum = 0 InvokeControl(Label_SelectedFolders, Sub(x) x.Text = "0 folders selected") Else InvokeControl(Label_SelectedFolders, Sub(x) x.Text = labelnum & " folders selected") End If End Sub #End Region #Region "Buttons" ' Folder button Public Sub Button_SearchFolder_Click(sender As Object, e As EventArgs) Handles Button_SearchFolder.Click Dim folderselect As New Ookii.Dialogs.VistaFolderBrowserDialog folderselect.ShowNewFolderButton = True If folderselect.ShowDialog.ToString() = "OK" Then My.Settings.Valores = Nothing labelnum = 0 Label_SelectedFolders.Text = labelnum & " folders selected" userSelectedFolderPath = folderselect.SelectedPath My.Settings.folderpath = folderselect.SelectedPath My.Settings.Save() playerargs = Nothing Me.Size = New System.Drawing.Size(400, 550) Panel_Folders.Size = New System.Drawing.Size(360, 250) ProgressBar.Visible = True Updatecheckboxes_Start() End If End Sub ' Player button Public Sub Button_SearchPlayer_Click(sender As Object, e As EventArgs) Handles Button_SearchPlayer.Click Dim playerselected As New OpenFileDialog() playerselected.InitialDirectory = Environ("programfiles") playerselected.Title = "Select your favorite music player" playerselected.Filter = "Music players|bsplayer.exe;mpc.exe;mpc-hc.exe;mpc-hc64.exe;umplayer.exe;vlc.exe;winamp.exe;wmp.exe" PlayerDialog.FilterIndex = 1 Dim selection As System.Windows.Forms.DialogResult = playerselected.ShowDialog() If selection = DialogResult.OK Then userSelectedPlayerFilePath = playerselected.FileName My.Settings.playerpath = playerselected.FileName My.Settings.Save() End If FlushMemory("PlayDir") End Sub ' Refresh button Private Sub Button_Refresh_Click(sender As Object, e As EventArgs) Handles Button_Refresh.Click labelnum = 0 Label_SelectedFolders.Text = "0 folders selected" Updatecheckboxes_Start() End Sub ' Play button Public Sub Button_PLAY_Click(sender As Object, e As EventArgs) Handles Button_PLAY.Click Me.Focus() If Button_PLAY.Tag = "Cancel" Then Want_to_cancel_thread = True Want_to_abort_thread = True While Not Thread_is_completed = True Application.DoEvents() End While ProgressBar.ResetBar() ProgressBar.Max = 100 ProgressBar.Value = 0 Else If Not System. IO. File. Exists(Textbox_Player. Text) Then MessageBox.Show("You need to select a music player...", "PlayDir", MessageBoxButtons.OK, MessageBoxIcon.Error) Else If Not playerargs = Nothing Then Checkbox_Randomize.Enabled = False Checkbox_SelectAll.Enabled = False Button_PLAY.Image = My.Resources.Cancel_button Button_PLAY.Tag = "Cancel" Button_PLAY.BackColor = Color.Red ProgressBar.Max = 100 ProgressBar.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString If Checkbox_Randomize.Checked = True Then Thread_is_completed = False Dim thread_1 As System.Threading.Thread = New Threading.Thread(AddressOf mithread) thread_1.IsBackground = True thread_1.Start() While Not Thread_is_completed = True Application.DoEvents() End While Else If Not thread_1.ThreadState = Threading.ThreadState.AbortRequested Or Want_to_abort_thread = True Or Want_to_cancel_thread = True Then Process.Start(userSelectedPlayerFilePath, playerargs) End If End If If Checkbox_AutoClose.Checked = True And Not Want_to_cancel_thread = True Then Me.Close() Else If Textbox_Player.Text = "Select a music player..." Then MessageBox.Show("You need to select a music player...", "PlayDir", MessageBoxButtons.OK, MessageBoxIcon.Error) If Textbox_Folder.Text = "Select a folder..." Then MessageBox.Show("You need to open a folder with music files...", "PlayDir", MessageBoxButtons.OK, MessageBoxIcon.Error) MessageBox.Show("You need to select at least one folder...", "PlayDir", MessageBoxButtons.OK, MessageBoxIcon.Stop) End If End If Want_to_abort_thread = False Want_to_cancel_thread = False Button_PLAY.Image = My.Resources.Play Button_PLAY.Tag = "Play" Button_PLAY.BackColor = Color.SteelBlue ProgressBar.TextShow = ProgBar.ProgBarPlus.eTextShow.None Panel_Folders.Focus() Checkbox_Randomize.Enabled = True Checkbox_SelectAll.Enabled = True FlushMemory("PlayDir") End If End Sub ' Auto-close Public Sub Checkbox_AutoClose_CheckedChanged(sender As Object, e As EventArgs) Handles Checkbox_AutoClose.CheckedChanged If Checkbox_AutoClose.Checked = True Then Picturebox_AutoClose.Visible = True My.Settings.autoclose = True Else Picturebox_AutoClose.Visible = False My.Settings.autoclose = False End If Panel_Folders.Focus() My.Settings.Save() End Sub ' Randomize Public Sub Checkbox_Randomize_CheckedChanged(sender As Object, e As EventArgs) Handles Checkbox_Randomize.CheckedChanged If Checkbox_Randomize.Checked = True Then Picturebox_Randomize.Visible = True My.Settings.randomize = True Else Picturebox_Randomize.Visible = False My.Settings.randomize = False End If Panel_Folders.Focus() My.Settings.Save() End Sub ' Select ALL checkboxes Public Sub Checkbox_SelectAll_CheckedChanged(sender As Object, e As EventArgs) Handles Checkbox_SelectAll.CheckedChanged select_all_thread.Abort() select_all_thread = New Threading.Thread(AddressOf Select_or_unselect_all) select_all_thread.IsBackground = True select_all_thread.Start() Panel_Folders.Focus() End Sub Private Sub Select_or_unselect_all() CheckForIllegalCrossThreadCalls = False If Checkbox_SelectAll.Checked = False Then InvokeControl(Picturebox_SelectAll, Sub(x) x.Visible = False) InvokeControl(Checkbox_SelectAll, Sub(x) x.Text = "Select all") For Each ControlName In Panel_Folders.Controls ControlName.Checked = False Next Else InvokeControl(Picturebox_SelectAll, Sub(x) x.Visible = True) InvokeControl(Checkbox_SelectAll, Sub(x) x.Text = "Select none") For Each ControlName In Panel_Folders.Controls ControlName.Checked = True Next End If CheckForIllegalCrossThreadCalls = True FlushMemory("PlayDir") End Sub #End Region #Region "Drag & Drop" Private Sub Textboxes_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Textbox_Folder.DragDrop, Panel_Folders.DragDrop If e.Data.GetDataPresent(DataFormats.FileDrop) Then Dim Objetos As String() = e.Data.GetData(DataFormats.FileDrop) Dim attributes = Objetos(0) If System.IO.Directory.Exists(attributes) Then Textbox_Folder.Text = Objetos(0) userSelectedFolderPath = Objetos(0) My.Settings.folderpath = Objetos(0) My.Settings.Save() playerargs = Nothing Me.Size = New System.Drawing.Size(400, 540) Panel_Folders.Size = New System.Drawing.Size(360, 250) labelnum = 0 Label_SelectedFolders.Text = "0 folders selected" Updatecheckboxes_Start() Else MessageBox.Show("Invalid directory!", "PlayDir", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If End If End Sub Private Sub Textboxes_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Textbox_Folder.DragEnter, Panel_Folders.DragEnter If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.All End If End Sub #End Region #Region " Notify icon " ' Form resize Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize If Me.WindowState = FormWindowState.Minimized Then Me.WindowState = FormWindowState.Normal Me.Hide() End If FlushMemory("PlayDir") End Sub ' Double click Private Sub NotifyIcon1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick If Me.Visible = True Then Me.Hide() Else Me.Show() End If FlushMemory("PlayDir") End Sub ' right click Private Sub NotifyIcon1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick If e.Button = MouseButtons.Right Then NotifyIcon1.ContextMenuStrip.Show() FlushMemory("PlayDir") End Sub ' Mostrar Private Sub MostrarToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ContextMenuStrip1.Click Me.Show() FlushMemory("PlayDir") End Sub ' Ocultar Private Sub OcultarToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles Ocultar.Click Me.Hide() FlushMemory("PlayDir") End Sub ' Salir Private Sub SalirToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles Salir.Click Me.Close() End Sub #End Region #Region " Tooltip events " Private Sub SuperTooltip_TooltipClosed(sender As Object, e As EventArgs) Handles SuperTooltip1.TooltipClosed FlushMemory("PlayDir") End Sub #End Region #Region " Randomize Thread " Public thread_1 As System.Threading.Thread = New Threading.Thread(AddressOf mithread) Public Sub mithread() Dim Str As String Dim Pattern As String = ControlChars.Quote Dim ArgsArray() As String Str = Replace(playerargs, " " & ControlChars.Quote, "") ArgsArray = Split(Str, Pattern) Using objWriter As New System.IO.StreamWriter(Temp_file, False, System.Text.Encoding.UTF8) Dim n As Integer = 0 Dim count As Integer = 0 Dim foldercount As Integer = -1 foldercount += 1 If foldercount > 1 Then InvokeControl(ProgressBar, Sub(x) x.Max = foldercount) End If Next If foldercount = 1 Then Dim di As New IO. DirectoryInfo(folder) Dim files As IO. FileInfo() = di. GetFiles("*") InvokeControl (ProgressBar, Sub(x ) x. Max = files. Count) If Want_to_abort_thread = False And Want_to_cancel_thread = False Then n += 1 CheckPrimeNumber(n) count += 1 If file. Extension. ToLower = ".lnk" Then Dim ShotcutTarget As String = Shortcut. ResolveShortcut((file. FullName). ToString()) objWriter.Write(ShotcutTarget & vbCrLf) Else objWriter. Write(file. FullName & vbCrLf ) End If Else Exit For End If Next End If Next ElseIf foldercount > 1 Then Dim di As New IO. DirectoryInfo(folder) Dim files As IO. FileInfo() = di. GetFiles("*") If Want_to_abort_thread = False And Want_to_cancel_thread = False Then If file. Extension. ToLower = ".lnk" Then Dim ShotcutTarget As String = Shortcut. ResolveShortcut((file. FullName). ToString()) objWriter.Write(ShotcutTarget & vbCrLf) Else objWriter. Write(file. FullName & vbCrLf ) End If Else Exit For End If Next End If InvokeControl(ProgressBar, Sub(x) x.Value += 1) Next End If End Using If Not thread_1.ThreadState = Threading.ThreadState.AbortRequested And Not Want_to_abort_thread = True And Not Want_to_cancel_thread = True Then Randomize_a_file.RandomizeFile(Temp_file) InvokeControl(ProgressBar, Sub(x) x.Value = 0) Try Process.Start(userSelectedPlayerFilePath, ControlChars.Quote & Temp_file.ToString() & ControlChars.Quote) Catch End Try End If Thread_is_completed = True End Sub #End Region #Region " Check prime number function " Private Sub CheckPrimeNumber(ByVal number As Integer) Dim IsPrime As Boolean = True For i = 2 To number / 2 If (number Mod i = 0) Then IsPrime = False Exit For End If Next i If IsPrime = True Then InvokeControl(ProgressBar, Sub(x) x.Value = number) End If End Sub #End Region #Region " InvokeControl " Public Sub InvokeControl(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T)) If Not Want_to_abort_thread = True Then Try If Control.InvokeRequired Then Control.Invoke(New Action(Of T, Action(Of T))(AddressOf InvokeControl), New Object() {Control, Action}) Else Action(Control) End If Catch End Try End If End Sub #End Region #Region "Flush memory" Public Sub FlushMemory(process_to_flush) Try GC.Collect() GC.WaitForPendingFinalizers() If (Environment.OSVersion.Platform = PlatformID.Win32NT) Then SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1) Dim myProcesses As Process() = Process.GetProcessesByName(process_to_flush) Dim myProcess As Process For Each myProcess In myProcesses SetProcessWorkingSetSize(myProcess.Handle, -1, -1) Next myProcess End If Catch End Try End Sub #End Region End Class
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: spiritdead en 4 Enero 2013, 12:01 pm
no he terminado de leerlo, pero puedo decir
para ser 1 simple aplicacion veo un uso excesivo de threads,y codigo .... no me imagino en 1 proyecto de mas de 30mil lineas :S
aver si le echo 1 ojo
siempre digo, los programadores no terminan de quemar la etapa del "hola mundo" por asi decirlo, cuando ya quieren ir a lo complejo, y terminan creando aplicaciones mal diseñadas....
prueba en la linea 79 poner me.refresh, estoy seguro q no muestra el form, debido a las tareas del thread, posiblemente ya que el hilo esta siendo ejecutado en el preload del form... (no he revisado el codigo fue simplemente viendolo por encima)
PORFAVOR ' Flush memory Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer no uses API sin saber su verdadero USO.
esta api es la encargada de liberar la ram usada y mandarla al disco duro, no la "libera" para eso esta el GC del framework que se encarga de la administracion de los recursos.
al usar dicha api 2-3 veces reduciras el rendimiento del software un 50-75% ya que debe hacer uso del discoduro para leer
tienes un verdadero desastre en esta funcion updatecheckboxes....
haces invoke en 1 therad hijo ? god...
uno en HILO llama a una funcion delegada que el delegado hace un Invokerequired pero.... joder
otra cosa.. consumes 40-50mb DEBIDO a que carga parcialmente o completamente algunos modulos del Framework...
recuerdalo VBNET/c# es 1 lenguaje administrado por el framework :)
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: Eleкtro en 4 Enero 2013, 12:31 pm
Gracias por comentar para ser 1 simple aplicacion veo un uso excesivo de threads,y codigo .... no me imagino en 1 proyecto de mas de 30mil lineas :S Entonces quizás no séa tán simple, Uso un hilo para dibujar los checkboxes en el panel Otro hilo para la casilla de "select all" (Para marcar/desmarcar todos los checkboxes) Y otro hilo para el botón azúl de "play", para randomizar los archivos cuando la opción está activada. Necesito usar los 3 threads símplemente para que no se cuelgue el form mientras se procesa esas cosas, creo que he hecho lo más correcto, lo erróneo habría sido dejar que el form se cuelgue mientras trabaja, vaya... si hay otra forma de hacerlo sin threads no sé hacerlo pero podrías decirme.
prueba en la linea 79 poner me.refresh, estoy seguro q no muestra el form, debido a las tareas del thread, posiblemente ya que el hilo esta siendo ejecutado en el preload del form... (no he revisado el codigo fue simplemente viendolo por encima) Eso antes no era un thread, la aplicación tardaba en iniciarse más como he comentado, lo puse en un thread y ahora tarda 1-2 segundos menos. He probado con el me.refresh justo debajo de llamar a ese thread como me has dicho, no lo ha solucionado :-\.
PORFAVOR ' Flush memory Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer no uses API sin saber su verdadero USO. No puedo decir que séa mentira lo que dices porque efectívamente no tengo idea de lo que hace la función de esa API, ví el snippet, leí muy buenos comentarios acerca del snippet, y lo usé, pero lo que si puedo afirmar es que he monitorizado la aplicación, la app no crea ni "dumpea" memória por así decirlo en ningún archivo del disco duro cuando uso la función de esa API[/b][/i], además el rendimiento no disminuye nada (Al menos en esta app) mejora complétamente, y se nota consideráblemente, el proceso de randomizado aumenta de velocidad en más de un 50%, y es por hacer uso de esa API, hice muchos tests estos días comparando velocidad y estoy seguro de esto que digo.
haces invoke en 1 therad hijo ? god... Perdona que vuelva a discrepar, pero no sé cual es el error que dices que he cometido en ese thread, si no uso los delegados en ese thread, manda el típico error de "cross-thread operation", por eso invoco los controles. PD: Como puedes ver no hago las cosas a lo loco. Un saludo!
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: spiritdead en 4 Enero 2013, 12:50 pm
Gracias por comentar
Entonces quizás no séa tán simple,
Uso un hilo para dibujar los checkboxes en el panel Otro hilo para la casilla de "select all" (Para marcar/desmarcar todos los checkboxes) Y otro hilo para el botón azúl de "play", para randomizar los archivos cuando la opción está activada.
Necesito usar los 3 threads símplemente para que no se cuelgue el form mientras se procesa esas cosas, creo que he hecho lo más correcto, lo erróneo habría sido dejar que el form se cuelgue mientras trabaja, vaya... si hay otra forma de hacerlo sin threads no sé hacerlo pero podrías decirme.
Eso antes no era un thread, la aplicación tardaba en iniciarse más como he comentado, lo puse en un thread y ahora tarda 1-2 segundos menos.
He probado con el me.refresh justo debajo de llamar a ese thread como me has dicho, no lo ha solucionado :-\.
No puedo decir que séa mentira lo que dices porque efectívamente no tengo idea de lo que hace la función de esa API, ví el snippet, leí muy buenos comentarios acerca del snippet, y lo usé,
pero lo que si puedo afirmar es que he monitorizado la aplicación, la app no crea ni "dumpea" memória por así decirlo en ningún archivo del disco duro cuando uso la función de esa API[/b][/i],
además el rendimiento no disminuye nada (Al menos en esta app) mejora complétamente, y se nota consideráblemente, el proceso de randomizado aumenta de velocidad en más de un 50%, y es por hacer uso de esa API, hice muchos tests estos días comparando velocidad y estoy seguro de esto que digo.
Perdona que vuelva a discrepar, pero no sé cual es el error que dices que he cometido en ese thread, si no uso los delegados en ese thread, manda el típico error de "cross-thread operation", por eso invoco los controles.
PD: Como puedes ver no hago las cosas a lo loco.
Un saludo!
nose para q pierdo el tiempo pero bueno. en otro post te dije la forma correcta y te puse 1 ejemplo de delegados en 1 hilo siempre se hace 'dentro del hilo SetLabelText(parametro1,parametro2) 'fuera del hilo seria asi mas o menos Delegate Sub SetLabelT(ByVal objeto As Object, ByVal texto As String) Private Sub SetLabelText(ByVal objeto As Object, ByVal texto As String) If CType(objeto,Label).InvokeRequired Then Dim d As New SetLabelT(AddressOf SetLabelText) Me.Invoke(d, New Object() {objeto, texto}) Else CType(objeto, Label).Text = texto End If End Sub
esa seria 1 FORMA GENERICA de un delegado para todos los label q requieran dicha funcion lo del me.refresh fue fallo mio, despues lei bien y la instruccion anterior no era del hilo era 1 funcion meramente No puedo decir que séa mentira lo que dices porque efectívamente no tengo idea de lo que hace la función de esa API, ví el snippet, leí muy buenos comentarios acerca del snippet, y lo usé,
me das la razon, NO LEES! y pones por poner codigo, eso es lo q me molesta! si no te documentas, esto es lo q pasa, 300 post en el foro... 1 ejemplo de niños. no te has dado cuenta q cuando una aplicacion consume ram excesivamente, el resto de las aplicaciones "pesan menos" si le ves desde el task maanger ? eso es debido a que van haciendo resize del ram, para evitar 1 desbordamiento, q da como resultado pareciera q la memoria nunca se acaba PERO hace tu pc 50% mas lenta, debido a q toma sectores del disco como memoria ram adicional (virtual)
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: seba123neo en 4 Enero 2013, 13:57 pm
esto es algo que lo tendrias que solucionar vos mismo, porque es facil saber que es lo que esta causando esto.
es super facil darse cuenta que es lo que esta tardando, si sabes poner puntos de interrupcion en el codigo lo tendrias que saber, simplemente comenta la linea que comienza el thread, si la ejecutas y abre normal entonces lo que tarda es ese thread. anda comentando lineas esa es la forma de darse cuenta en 1 minuto que es lo que tarda.
y mi opinion es que toda esa porqueria del GDI+(no lo digo por tu proyecto sino en general el GDI depende como lo manejes es lento) es lo que tarda en dibujarse, todo es una suma de cosas que van poniendo lento, y si aparte usas degradado y le dibujas arriba y controles de terceros que hay que cargarlos a la memoria es mas lento todavia va a ser, es asi. si embebes 3 dll de 5 megas es casi una locura diria yo ya que el tamaño del .exe se va por las nubes.
tenes que ir linea por linea viendo que e lo que tarda no hay otra.
y no esta bien usar el collect del garbage collector, pues es una forma de limpiar algo que esta funcionando mal, el mismo .net ya se encarga de eso no tendrias que llamarlo, y si consume mucho es por la cantidad de cosas que dije antes.
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: Eleкtro en 10 Enero 2013, 01:13 am
Definitívamente lo que está causando que la APP tarde 10 segundos en cargar son los controles del "DotNetBar", serán controles muy buenos y todo lo que quieras (spiritdead), pero son pesadísimos a la hora de cargar, no creo que valga la pena usarlos para que luego séa incómodo abrir la APP, y eso que solo uso 2 groupboxes y un panel... no me imagino si usase más controles de esa suite.
En otra aplicación que estoy haciendo, nada más cargar la aplicación dibuja +20 botones con 1 imagen en cada botón, 4 picturebox, 1 listview, 1 textbox, el executable está comprimido, además de cargar +250 recursos de texto al inicio, pues no me tarda ni 1,5 segundos en cargarse la APP, claro, porque no he usado krypton ni DotNetBar esta vez.
Un saludo!
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: spiritdead en 10 Enero 2013, 01:19 am
Definitívamente lo que está causando que la APP tarde 10 segundos en cargar son los controles del "DotNetBar", serán controles muy buenos y todo lo que quieras (spiritdead), pero son pesadísimos a la hora de cargar, no creo que valga la pena usarlos para que luego séa incómodo abrir la APP, y eso que solo uso 2 groupboxes y un panel... no me imagino si usase más controles de esa suite.
En otra aplicación que estoy haciendo, nada más cargar la aplicación dibuja +20 botones con 1 imagen en cada botón, 4 picturebox, 1 listview, 1 textbox, el executable está comprimido, además de cargar +250 recursos de texto al inicio, pues no me tarda ni 1,5 segundos en cargarse la APP, claro, porque no he usado krypton ni DotNetBar esta vez.
Un saludo!
yo use fue krypton :P q cargan en 1-2 segs
Título: Re: Mi app tarda demasiado en iniciar
Publicado por: seba123neo en 10 Enero 2013, 01:37 am
Definitívamente lo que está causando que la APP tarde 10 segundos en cargar son los controles del "DotNetBar"
es asi, los controles de terceros (esos packs de varios controles sobre todo), son lindos y todo, pero asi le cuestan a la aplicacion, las hacen mas lenta y te lo puedo asegurar ya que a mi tambien me encanta dejar la interfaz perfecta con iconos lindos y demas, soy capas de perder solo un dia para decidirme solo que icono ponerle. >:D yo en una aplicacion use un pack de 60 controles gratis que daba la empresa DevExpress (es una de las mejores junto a la krypton de componentfactory), use una grilla, unos datapicker y unos frames, que paso la aplicacion funcionaba bien, pero veia que era algo lenta al cargar y no era fluida como una pantalla sin esos controles, a la aplicacion le cuesta un monton dibujar esos controles y te lo puedo demostrar con una aplicacion que muestra los objetos gdi en memoria. entonces me decidi por hacerlos con controles comunes del visual studio y vuela, los saque a la ***** a esos controles, son lindos y todo, hasta el label que traia era pesado, y eso que yo puse pocos controles no me imagino con muchos, tienen miles de propiedades pero son pesados y te puedo asegurtar que no valen la pena, aparte de que tenes que llevar esas librerias, y si la llegas a embeber dentro del .exe te aumentan como 15 megas de tamaño, una total locura. lo que hay que hacer es la aplicacion linda, pero lo mas rapido posible, no meterle 80 controles y para colmo todos externos eso lo pone re lento, ni hacer esas cosaas de tranparecia y despues para colmo dibujarle arriba, eso le "cuesta". lo unico que uso externo por ahora es el objectlistview, que es una grilla irremplazable y rapidisima y el mejor control para .NET que he visto, y solo pesa 300 kb. esa es mi opinion y consejo, que trates de no dibujar tantas cosas en un formulario, se puede hacer linda una pantalla con solo iconos de 16x16 y sin dibujar ningun degradado y con los mismo controles de .NET saludos.
Título: Re: [SOLUCIONADO] Mi app tarda demasiado en iniciar
Publicado por: Eleкtro en 10 Enero 2013, 01:44 am
Hombre, pero también he descubierto que los controles de terceros por así decirlo..."gratis", por ejemplo los que hay en CodeProject, como el objectlistview, más de uno son buenisímos y no les cuesta nada cargar, claro, solo pesan unos pocos KB en lugar de los muchos MB que pesan los controles DE PAGO, y las muchas más diferencias (que desconozco) que tienen los de pago que los hacen tán pesados. Ahora encontré un panel degradado gratis, no tarda nada en cargar, está muy bien, aquí lo dejo por si alguien lo necesita :) GradientPanel.vbImports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Text Imports System.Windows.Forms Namespace GradientPanel Public Partial Class GradientPanel Inherits System.Windows.Forms.Panel ' member variables Private mStartColor As System.Drawing.Color Private mEndColor As System.Drawing.Color Public Sub New() ' InitializeComponent() PaintGradient() End Sub Protected Overrides Sub OnPaint(pe As PaintEventArgs) ' TODO: Add custom paint code here ' Calling the base class OnPaint MyBase.OnPaint(pe) End Sub Public Property PageStartColor() As System.Drawing.Color Get Return mStartColor End Get Set mStartColor = value PaintGradient() End Set End Property Public Property PageEndColor() As System.Drawing.Color Get Return mEndColor End Get Set mEndColor = value PaintGradient() End Set End Property Private Sub PaintGradient() Dim gradBrush As System.Drawing.Drawing2D.LinearGradientBrush gradBrush = New System.Drawing.Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(Me.Width, Me.Height), PageStartColor, PageEndColor) Dim bmp As New Bitmap(Me.Width, Me.Height) Dim g As Graphics = Graphics.FromImage(bmp) g.FillRectangle(gradBrush, New Rectangle(0, 0, Me.Width, Me.Height)) Me.BackgroundImage = bmp Me.BackgroundImageLayout = ImageLayout.Stretch End Sub End Class End Namespace
Título: Re: [SOLUCIONADO] Mi app tarda demasiado en iniciar
Publicado por: seba123neo en 10 Enero 2013, 01:54 am
si, los controles realizados asi que heredan (Inherits), son controles rapidos, pues lo unico que estas haciendo es usar el mismo control de .NET y le estas modificando sus metodos para hacer lo que uno quiera, a mi tambien me gustan ese tipo de controles, pero la verdad no se porque son tan pesados esos packs de controles de esas empresas, y para colmo hay que pagar, ni en pedo pago para que me haga mas lenta la aplicacion :xD
yo antes tenia este orden de prioridad:
INTERFAZ LINDA - APLICACION RAPIDA
despues cambie a
APLICACION RAPIDA - INTERFAZ LINDA
ya que me encanta primero buscar que las cosas funcionen lo mas rapido posible, luego ver los procesos que tardan mas y si hay posibilidad de optimizarlos. y mientras menos dependencias mejor, que solo sea el .exe y nada mas.
Título: Re: [SOLUCIONADO] Mi app tarda demasiado en iniciar
Publicado por: Eleкtro en 10 Enero 2013, 02:24 am
Esta es la misma aplicación que posteé, pero usando la classe del GradientPanel que he comentado antes, y un control GRATIS de groupbox degradado que se llama "The Grouper":
(http://img846.imageshack.us/img846/526/prtscrcapture2p.jpg)
La diferencia visual es mínima y la diferencia de carga es brutal, no llega ni a 1 segundo de carga, cuando antes tardaba unos 7-10 seg.
· Saquen sus propias conclusiones sobre los comentarios de Seba123Neo y mis pruebas xD, si quieren una APP linda busquen controles gratis antes que contorles de pago!
PD: Aún me falta testear lo que comenta spiritdead sobre los controles de krypton, pero bueno, no seré pesado haciendo otro comentario, el tema está más que hablado y solucionado.
Gracias por leer.
Título: Re: [SOLUCIONADO] Mi app tarda demasiado en iniciar
Publicado por: spiritdead en 10 Enero 2013, 02:25 am
Esta es la misma aplicación que posteé, pero usando la classe del GradientPanel que he comentado antes, y un control GRATIS de groupbox degradado que se llama "The Grouper": (http://img846.imageshack.us/img846/526/prtscrcapture2p.jpg) La diferencia es mínima pero la diferencia de carga es brutal, no llega ni a 1 segundo de carga, cuando antes tardaba unos 7-10 seg. - Saquen sus propias conclusiones sobre los comentarios de Seba123Neo y mis pruebas xD, si quieren una APP linda busquen controles gratis antes que contorles de pago!
PD: Aún me falta testear lo que comenta spiritdead sobre los controles de krypton, pero bueno, no seré pesado haciendo otro comentario, el tema está más que hablado y solucionado.
Gracias por leer.
siempre y cuando tengas cuidado con el load, carga rapido o almenos yo uso mas de 100 controles y carga en 3 seg
|