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:
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:
Código
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 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 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 If Want_to_abort_thread = False And Want_to_cancel_thread = False Then n += 1 CheckPrimeNumber(n) count += 1 objWriter.Write(ShotcutTarget & vbCrLf) Else End If Else Exit For End If Next End If Next ElseIf foldercount > 1 Then If Want_to_abort_thread = False And Want_to_cancel_thread = False Then objWriter.Write(ShotcutTarget & vbCrLf) Else 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