+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 5 su 5

Discussione: Out of memory con StringBuilder

  1. #1
    SebastianoFloridia non è in linea Scolaretto
    Post
    142

    Out of memory con StringBuilder

    Salve a tutti.
    Ho un problema di memoria con l'uso di stringbuilder.
    devo costruire dei reports numerici lunghissimo, anche 1000 pagine.
    In cascata aggiungo dati alla variabile ma a metà lavoro, ottengo un "out of memory".
    Sono testi con tag rtf.

    Nella stessa tipologia di codice nel vecchio software fatto in vb6, con la stessa operazione riuscivo ad ottenere centinaia di pagine senza mai un errore.
    Il limite di StringBuilder è Int32.
    c'è un modo alternativo per risolvere (magari senza stringbuilder).
    GRazie
    Sebastiano Floridia

    codice:
    StringBuilder rtf = new StringBuilder();
                    TxtReportFEM.DeselectAll();
                    TxtReportFEM.Clear();
    
                    rtf.Append(@"{\rtf1"); //beginning of rtf  
                    rtf.Append(@"{\fonttbl{\f0\froman \fcharset0 Times New Roman; } {\f1\fswiss Arial; } {\f2\fswiss \fcharset0 Tahoma; }{\f3 \fswiss \fcharset0 Arial;}{\f4 \fswiss TAHOMA;}{\f5 \froman \fcharset2 Symbol;}{\f6 \froman Times New Roman;}} \n");
                    rtf.Append(@"{\colortbl ;\red255\green255\blue255 ;\red0\green0\blue0 ;\red255\green0\blue0 ;\red0\green0\blue255 ;\red192\green192\blue192 ;\red245\green245\blue245 ;\red135\green135\blue135 ;\red225\green225\blue225; } \n");
                    rtf.Append(@"{\stylesheet{\f1\fs24\cf2\cb1\ulc2 Normal;}{\cs1\cf2\cb1\ulc2 Default Paragraph Font;}{\s2\snext0\cf0\cb1\ulc0 ;}{\s3\snext3\fs24\cf2\cb1\ulc0 Stile;}} \n");
                    rtf.Append(@"\paperw16838\paperh11906");
                    rtf.Append(@"\widowctrl\ftnbj\ftnrestart \sectd \linex0\endnhere\deflang1040");
                    RelInput = "";
                    Contenuto = "";
                    ReportStruttura.Apri(ref Contenuto);
                    RelInput = RelInput + Contenuto;
                    ReportStruttura.SollecitazioneAsteStatica(ref Contenuto);
                    RelInput = RelInput + Contenuto;
                    ReportStruttura.SollecitazioneAsteSismicaSLD(ref Contenuto);
                    RelInput = RelInput + Contenuto;
                    ReportStruttura.SollecitazioneAsteSismicaSLU(ref Contenuto);
                    RelInput = RelInput + Contenuto;
                    rtf.Append(@"\par " + RelInput);
    
                    rtf.Append(@"\pard");
                    rtf.Append(@"}");
                   
                    SaveFileDialog1.FileName = Globale.NomeCompletoCartellaReports + "\\SollecitazioniAste.rtf";
                    TxtReportFEM.Rtf = rtf.ToString();
                    TxtReportFEM.SaveFile(SaveFileDialog1.FileName);

  2. #2
    L'avatar di AntonioG
    AntonioG non è in linea Moderatore Globale Ultimo blog: Commodore 64 e Codemotion
    Luogo
    Roma
    Post
    16,400
    Blogs
    5
    Semplicemente non usare la stringbuilder per salvare il file in una sola volta ma apri il file e scrivi stringa dopo stringa.
    Avvisi generali e importanti, a pena CHIUSURA thread e/o BAN
    Il crossposting è vietato.
    Le richieste di "pappa pronta" sono vietate.
    Utilizzate i tag CODE per il codice.
    Leggere il Regolamento per chiarimenti PRIMA di creare nuovi thread.
    Utilizzare sempre i PM per comunicare con i moderatori.
    Non mi contattate in PM per problemi di software, usate il forum

  3. #3
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,158
    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    Ho un problema di memoria con l'uso di stringbuilder.
    devo costruire dei reports numerici lunghissimo, anche 1000 pagine.
    In cascata aggiungo dati alla variabile ma a metà lavoro, ottengo un "out of memory".
    L'uso di StringBuilder è pensato per migliorare le performance di costruzione di una stringa componendola gradualmente senza incappare nella creazione di miriadi di oggetti, a causa del fatto che le stringhe in .NET sono immutabili.

    Nonostante questo, quando si arriva a una lunghezza importante del testo, la memoria tende a esaurirsi comunque.

    In alternativa, usa la classe StreamWriter (qui la documentazione): ha molti metodi simili allo StringBuilder ma scrive direttamente all'interno dello Stream sottostante, in modo ottimizzato (es. a blocchi), che potrebbe essere costituito da una istanza di FileStream ossia da un file aperto in cui riportare il testo.

    Io avrei adottato comunque questo approccio, che è senz'altro più "conservativo" in termini di RAM quando nella maggior parte dei casi sei consapevole che il testo tende a essere piuttosto lungo, evitando così la possibilità di incappare in un Out Of Memory a prescindere.

    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    Nella stessa tipologia di codice nel vecchio software fatto in vb6, con la stessa operazione riuscivo ad ottenere centinaia di pagine senza mai un errore.
    Il limite di StringBuilder è Int32.
    Questo è probabilmente dovuto al fatto che .NET rappresenta i caratteri nel formato UTF-16 in memoria, quindi usa almeno due byte per ciascun carattere, mentre VB6
    - se non ricordo male - usava la codifica ANSI, quindi un solo byte.

    Il raddoppio delle dimensioni probabilmente ti ha portato ad avere il problema. Però risolvendo il problema, avrai un software migliore e più stabile.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  4. #4
    SebastianoFloridia non è in linea Scolaretto
    Post
    142
    Grazie a tuti!!!
    Risolto con il semplice contatenamento stringhe.
    2200 pagine in due minuti!!!

    Grazie
    Sebastiano Floridia

  5. #5
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,158
    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    Risolto con il semplice contatenamento stringhe.
    2200 pagine in due minuti!!!
    Risolvere un problema passando dallo StringBuilder a un concatenamento di stringhe, cioè alla versione equivalente ma più lenta e dispendiosa di RAM che crea una miriade di oggetti, è alquanto strano.

    A questo punto sono convinto che il problema fosse da imputare ad altro.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi