[VB.NET] BackgroundWorker, non capisco dove sia l'errore

giovedì 16 gennaio 2014 - 10.09
Tag Elenco Tags  VB.NET  |  .NET 4.0  |  Visual Studio 2010

Zan Profilo | Newbie

Buongiorno a tutti,
espongo subito il problema:
ho un piccolo programma che mi scansiona una serie di cartelle sul server e mi salva il tutto su un db sql, il tutto + o - funziona se lancio il tutto dal form principale.
La cosa non va quando tento di portare quest'accrocchio su un BackgroundWorker. Va subito in errore "al comando è già associato un datareader aperto che deve essere chiuso".
Mi potete controllare il codice per favore ?

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
ScansionaServer()
End Sub




Private Sub ScansionaServer()
Try
ElencaCartelle()

'===SCANSIONA TUTTE LE CARTELLE DEL SERVER PER ELENCARE I FILES CONTENUTI===
' GET RECURSIVE LIST OF ALL FILES STARTING IN THIS DIRECTORY.
Dim List As List(Of String) = Me.GetFilesRecursive(PercorsoServer)
Dim Path As String

'===RIPULISCO LA TABELLA
Dim cmdDelete As SqlCommand = conn.CreateCommand()
cmdDelete.Connection = conn
cmdDelete.CommandText = "DELETE FROM FIPflow_ElencoFilesServer"
cmdDelete.ExecuteNonQuery()
cmdDelete.Dispose()

' LOOP THROUGH AND DISPLAY EACH PATH.
For Each Path In List

'===AGGIUNGO IL PERCORSO DEL FILE AL DB===
Dim cmd As SqlCommand
Dim sqlStr As String = ""
Dim MyFile As New FileInfo(Path)
Dim PathDestinazione As String = Replace(Path, PercorsoServer, "")

sqlStr = "INSERT INTO FIPflow_ElencoFilesServer(Percorso,NomeFile,DimensioneFile,UltimaModificaFile,TipoFile,Cartella) VALUES(@Percorso,@NomeFile,@DimensioneFile,@UltimaModificaFile,@TipoFile,@Cartella)"
cmd = New SqlCommand(sqlStr, conn)
cmd.Parameters.AddWithValue("@Percorso", PathDestinazione)
cmd.Parameters.AddWithValue("@NomeFile", SoloNomeFile(PathDestinazione))
cmd.Parameters.AddWithValue("@DimensioneFile", Fix(MyFile.Length / 1024))
cmd.Parameters.AddWithValue("@UltimaModificaFile", MyFile.LastWriteTime)
cmd.Parameters.AddWithValue("@TipoFile", SoloEstensioneFile(PathDestinazione))
cmd.Parameters.AddWithValue("@Cartella", SoloPercorso(PathDestinazione))
cmd.ExecuteNonQuery()
cmd.Dispose()
Next

Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "Titolo", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub



Public Sub ElencaCartelle()
Try
Dim rootDir As String

'===RIPULISCO LA TABELLA
Dim cmdDelete As SqlCommand = conn.CreateCommand()
cmdDelete.Connection = conn
cmdDelete.CommandText = "DELETE FROM FIPflow_StrutturaServer"
cmdDelete.ExecuteNonQuery()
cmdDelete.Dispose()

For Each rootDir In Directory.GetLogicalDrives
ScanDirTree(PercorsoServer)
Next


'===ELIMINA I DUPLICATI===
Dim mycommand As SqlClient.SqlCommand = New SqlClient.SqlCommand()
mycommand.Connection = conn
mycommand.CommandText = "DELETE FROM FIPflow_StrutturaServer WHERE ID NOT IN(Select MAX(ID) FROM FIPflow_StrutturaServer GROUP BY Percorso)"
mycommand.ExecuteNonQuery()
mycommand.Dispose()
'=========================


Catch ex As Exception
ScriviLog("Errore durante la creazione dell'elenco cartelle (" & ex.Message & ") " & Now)
End Try
End Sub





Sub ScanDirTree(ByVal dir As String, Optional ByVal livello As Integer = 0)
Dim SubDir As String
Try

'===SALVO IL PERCORSO DEL TIPO \PROVA\PIPPO\1 NEL DB (SQL)
Dim myCommand As SqlCommand = conn.CreateCommand()
myCommand.Connection = conn
myCommand.CommandText = "INSERT INTO FIPflow_StrutturaServer (Percorso) VALUES (@Percorso)"
myCommand.CommandType = CommandType.Text
myCommand.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Percorso", System.Data.SqlDbType.VarChar, 500, "Percorso"))
myCommand.Parameters(0).Value = Replace(dir, PercorsoServer, "") 'CANCELLO IL PERCORSO PRINCIPALE DEL SERVER)
myCommand.ExecuteScalar()
myCommand.Dispose()

For Each SubDir In Directory.GetDirectories(dir)
ScanDirTree(SubDir, livello + 1)
Application.DoEvents()
Next



Catch ex As Exception
ScriviLog("Errore durante la scansione delle cartelle (" & ex.Message & ") " & Now)
End Try
End Sub




Public Function GetFilesRecursive(ByVal initial As String) As List(Of String)
' THIS LIST STORES THE RESULTS.
Dim result As New List(Of String)

' THIS STACK STORES THE DIRECTORIES TO PROCESS.
Dim stack As New Stack(Of String)

' ADD THE INITIAL DIRECTORY
stack.Push(initial)

' CONTINUE PROCESSING FOR EACH STACKED DIRECTORY
Do While (stack.Count > 0)
' GET TOP DIRECTORY STRING
Dim dir As String = stack.Pop
Try
' ADD ALL IMMEDIATE FILE PATHS
result.AddRange(Directory.GetFiles(dir, "*.*"))

' LOOP THROUGH ALL SUBDIRECTORIES AND ADD THEM TO THE STACK.
Dim directoryName As String
For Each directoryName In Directory.GetDirectories(dir)
stack.Push(directoryName)
Next

Catch ex As Exception
End Try
Loop

' RETURN THE LIST
Return result
End Function

Grazie mille a chiunque voglia/possa aiutarmi
R.Zanni

0v3rCl0ck Profilo | Guru

ciao, se riesci postaci l'eccezione completa, e dato che il listato è piuttosto lungo, se possibile estrai il codice in un progettino mantenendo l'indentazione, zippa il tutto e allega al post.



Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

Zan Profilo | Newbie

Ciao,
prima di tutto grazie per il tuo interessamento, poi, ecco lo "sgorbietto".

Saluti
R.Zanni

0v3rCl0ck Profilo | Guru

stavo dando un occhio all'app, e nella callback BackgroundWorker1_DoWork e quindi nel metodo ScansionaServer, non puoi più utilizzare nessun componente della form, ma puoi farlo solo nell'altra callback RunWorkerCompleted, il background worker è stato proprio ideato per evitare di dovere creare codice con i classici Thread per ritornare sul thread principale, perchè se provi a "toccare" un qualsiasi oggetto della form .net ti restituisce un errore. Devi fare tutta l'elaborazione preparare un output e settare la proprietà e.Result con i risultati, e poi nel RunWorkerCompleted fare gli aggiornamenti sulla form.


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

Zan Profilo | Newbie

Ciao,
grazie mille per la tua risposta.Farò delle prove e ti farò sapere.

PS
Scusa per la tarda risposta ma ero fuori ufficio

Grazie mille
R.Zanni

0v3rCl0ck Profilo | Guru

>Ciao,
>grazie mille per la tua risposta.Farò delle prove e ti farò sapere.

Aspetto tue news

>PS
>Scusa per la tarda risposta ma ero fuori ufficio

non ti preoccupare anche io a volte rispondo molto tardi, in base al carico di lavoro che ho in ufficio

>
>Grazie mille
>R.Zanni

figurati!


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic

Zan Profilo | Newbie

Ciao,
ho fatto delle prove e, sembrerebbe funzionare (spero bene...).

Grazie nuovamente per il tuo prezioso interessamento

Buona giornata
R.Zanni

0v3rCl0ck Profilo | Guru

>Ciao,
>ho fatto delle prove e, sembrerebbe funzionare (spero bene...).

bene bene

>
>Grazie nuovamente per il tuo prezioso interessamento
>

di niente, alla prossima


Michael Denny
Software Developer & Architect
http://blogs.dotnethell.it/Regulator/
http://dennymichael.wordpress.com
Twitter: @dennymic
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5