Oppure

Loading
24/02/14 11:17
ACecere
Salve a tutti,
è da qualche settimana che combatto con questo errore ed , essendo ormai sfiduciato, mi rivolgo a voi :hail:
In pratica, dopo circa 2 ore di esecuzione, mi si presenta l'errore "Risorse di sistema insufficienti"..

Il codice è il seguente :

Public Sub Lettura_Dati()
        Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB")
        Dim Query, Query2 As String
        Dim Cn As New OleDbConnection(Database)
        Cn.Open()
        Query = "Select Descrizione from Articoli group by Genere"
        Dim Conn As New OleDb.OleDbCommand(Query, Cn)
        Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader()
        While Rs.Read
            '############ TESTATE CAMPIONATO
            text2.text = Rs("Descrizione")
            Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'"
            Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn)
            Dim rs2 As OleDbDataReader = Conn2.ExecuteReader
            While rs2.Read
                '################################ INCONTRI 
                text1.text = rs2("Stato")
            End While
            rs2.Close()
            rs2 = Nothing
            Conn2.Dispose()
        End While
        Rs.Close()
        Rs = Nothing
        Cn.Dispose()
        Conn.Dispose()
    End Sub


L'errore me lo segnala sull'istruzione

Dim rs2 As OleDbDataReader = Conn2.ExecuteReader


Potreste aiutarmi a capire cosa c'è di errato nel codice ? :hail:

Grazie anticipatamente!
aaa
24/02/14 11:26
Snogar
prova a mettere un blocco try e metti le chiusure degli elementi del database nel finaly tanto per iniziare.

pio la conn2 la distruggi ad ogni ciclo while ....non ne capisco il senso :-?
aaa
24/02/14 11:44
ACecere
pensi che così vada meglio ?

        Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB")
        Dim Query, Query2 As String
        Dim Cn As New OleDbConnection(Database)
        Cn.Open()
        Query = "Select Descrizione from Articoli group by Genere"
        Dim Conn As New OleDb.OleDbCommand(Query, Cn)
        Try
            Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader()
            While Rs.Read
                text2.text = Rs("Descrizione")
                Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'"
                Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn)
                Dim rs2 As OleDbDataReader = Conn2.ExecuteReader

                While rs2.Read
                    text1.text = rs2("Stato")
                End While

                rs2.Close()
                rs2 = Nothing
            End While
        Catch es As Exception
            My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Errore", True)
        Finally
            Rs.Close()
            Rs = Nothing
            Cn.Dispose()
            Conn.Dispose()
            Conn2.Dispose()
        End Try
aaa
26/02/14 15:07
Ultimo

Risorse di sistema insuficenti = Mamma dammi i soldi che devo comprare altra RAM
If ok Then GOTO Avanza else GOTO Inizia

27/02/14 13:22
ACecere
16 Gb penso che bastino.. o no ?;)
aaa
27/02/14 15:52
Qwertj
Postato originariamente da Ultimo:


Risorse di sistema insuficenti = Mamma dammi i soldi che devo comprare altra RAM


O come buttare via i soldi spegnendo il cervello :_doubt:

While Rs.Read
    text2.text = Rs("Descrizione")
    Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'"
    Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn)
    Dim rs2 As OleDbDataReader = Conn2.ExecuteReader
 
    While rs2.Read
        text1.text = rs2("Stato")
    End While

    rs2.Close()
    rs2 = Nothing
End While

Allocare memoria in un ciclo, specialmente se si ripete così a lungo, è una PESSIMA pratica. :nono:

Se sei fortunato hai la GC che sputa sangue e un bel 200x di moltiplicatore sul tempo di esecuzione, se sei sfortunato (come nel tuo caso) finisci bellamente lo spazio in memoria.

Prova una cosa così
Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB")
'Query1 e Query2 sono inutili
Dim Cn As New OleDbConnection(Database)
Cn.Open()
Dim Conn As New OleDb.OleDbCommand("Select Descrizione from Articoli group by Genere", Cn)

Try
	
	Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader()
	Dim Conn2 As New OleDb.OleDbCommand() 'istanziato >una volta sola<
	Dim rs2 As OleDbDataReader
	Conn2.Connection = Cn
	
	While Rs.Read()
		Try
			text2.text = Rs("Descrizione")
			'sovrascrivo semplicemente la query senza creare un nuovo oggetto ogni volta
			Conn2.CommandText = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'"
			rs2 = Conn2.ExecuteReader()

			While rs2.Read()
				text1.text = rs2("Stato")
			End While
			
		Catch es As OutOfMemoryException
			GC.Collect() 'liberiamo un po' di memoria, se ce n'è avanzata...
			My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Warning: memory leak", True)
		Finally
			rs2.Close()
			rs2.Dispose() 'perchè lui niente dispose?
		End Try
	End While
	
Catch es As Exception
	'io aggiungerei qualcosa di descrittivo... tipo es.Message
	My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Errore", True)
Finally
	Rs.Close()
	Rs.Dispose() 'anche lui si merita un dispose
	Cn.Dispose()
	Conn.Dispose()
	Conn2.Dispose()
End Try

Questo dovrebbe ottimizzare il codice. Nota i Dispose() anche dove avevi i "= Nothing" e il non avere più nulla dichiarato dentro i cicli!
Inoltre Conn2 viene istanziato una volta sola e non a ogni iterazione, mangiandoti risorse a manetta

Sicuramente si può ottimizzare anche a livello algoritmico (tipo fare un'unica query?) ma non sapendo il funzionamento del programma mi riservo di lasciare a te questa parte.

Pensate mentre scrivete il codice! :rofl:
aaa
28/02/14 11:09
vankraster
[PseudoCodice] - Io uso C#
Io in genere faccio diversamente, l'idea non è quella di fare una query all'interno di ogni ciclo che ti succhia troppe risorse, ma:
riempire un datatable con tutti i valori con :
Datatable DT_RES= EseguiQuery(" Select Stato, Descrizione from Articoli";);
Poi dentro il ciclo fai
DT_RES.Select("Descrizione like '"+ Rs("Descrizione";) +"'" ) che ti restituisce un'array di datarow.
puoi fare comunque un :
foreach (datarow riga in DT_RES.Select("Descrizione like '%"+ Rs("Descrizione";) +"%'" ))

Non ho tempo di buttarti giù il codice, sono al lavoro ma la strada dovrebbe essere questa, e prova a usare gli using senza fare il manual dispose.
fai
Using Cn As New OleDbConnection(Database)
.....
End Using
e non c'è bisogno del dispose.
Ultima modifica effettuata da vankraster 28/02/14 11:10
aaa
04/03/14 11:24
ACecere
Grazie Mille a tutti!

Ho risolto seguendo il consiglio di Qwertj :k:
aaa