Async await

di il
31 risposte

31 Risposte - Pagina 2

  • Re: Async await

    Alka ha scritto:


    Comunque siamo abbondantemente OT.
    Giusto.
    @Pivello
    per ritornare in tema, un codice semplice, per saggiare come usare backgroundworker.
    Il codice sembra lungo perché ho inizializzato tutti gli strumenti da codice, le righe interessanti per far funzionare backgroundworker sono veramente poche e segnalate con: ti interessa, il resto è contorno:
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel; // contiene BackgroundWorker, ti interessa
    using System.Linq;
    using System.IO;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    /**********************************************
    *     CARICA UN FILE IN MODO ASINCRONO        *
    *  MOSTRA RIGA RIGA ATTRAVERSO UNA SCROLLBAR  *
    * CODICE WINFORM NULLA DA AGGIUNGERE SUL FORM *
    * ********************************************/
    
    namespace TestiGrandi // in Program.cs il namesapace deve corrispondere
    {
        public partial class Form1 : Form
        {
            private List<string> TESTOletto = new List<string>();
            private string Cx = "|/-\\";
            private byte n = 0;
            private Stopwatch StWa = new Stopwatch();
            // inseribili anche da progettazione ------------------------
            private OpenFileDialog openFile = new OpenFileDialog();
            private Timer timer1 = new Timer();
            private BackgroundWorker Worker = new BackgroundWorker(); // Worker lavorerà in asincrono, ti interessa
            private RichTextBox richTextBox1 = new RichTextBox();
            private HScrollBar hScrollBar1 = new HScrollBar();
            private Button Button1 = new Button();
            private Label Label1 = new Label();
            // ----------------------------------------------------------
            public Form1()
            {
                InitializeComponent();
                // inseribili anche da progettazione -------------------
                Controls.Add(richTextBox1);
                Controls.Add(hScrollBar1);
                Controls.Add(Button1);
                Controls.Add(Label1);
                hScrollBar1.Scroll += HScrollBar1_Scroll;
                Button1.Click += Button1_Click;
                timer1.Tick += Timer1_Tick;
                Worker.DoWork += Worker_DoWork; // attiva l'evento DoWork, ti interessa
                Worker.RunWorkerCompleted += Worker_RunWorkerCompleted; // attiva l'evento RunWorkerCompleted, ti interessa
                // ----------------------------------------------------
                // impostabili anche da progettazione -----------------
                richTextBox1.Location = new System.Drawing.Point(12, 84);
                richTextBox1.Size = new System.Drawing.Size(ClientSize.Width - 24, ClientSize.Height - 100);
                richTextBox1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;
                Button1.Location = new System.Drawing.Point(12, 14);
                Button1.Text = "LOAD";
                Label1.Location = new System.Drawing.Point(94, 19);
                Label1.AutoSize = false;
                Label1.Size = new System.Drawing.Size(40, 15);
                Label1.BackColor = System.Drawing.Color.Green;
                Label1.Visible = false;
                hScrollBar1.Location = new System.Drawing.Point(12, 52);
                hScrollBar1.Width = ClientSize.Width - 24;
                hScrollBar1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
                hScrollBar1.LargeChange = 1;
                timer1.Interval = 100;
                // ----------------------------------------------------
            }
    
            private void Button1_Click(object sender, EventArgs e)
            {
                LeggiFileTxt();
            }
    
            private void LeggiFileTxt()
            {
                openFile.Filter = "File di testo (*.txt)|*.txt|Tutti i file (*.*)|*.*";
                openFile.RestoreDirectory = true;
                if (openFile.ShowDialog() == DialogResult.OK) // modo corretto di impostare la dialog, per gestire anche annulla
                {
                    string PercorsoDelFile = openFile.FileName;
                    StWa.Reset(); // azzera il tempo
                    StWa.Start();
                    if (Worker.IsBusy)// si esce se il vecchio processo non è terminato, ti interessa
                    {
                        return;
                    }
                    Worker.RunWorkerAsync(PercorsoDelFile); // richiama Worker_DoWork e passa il percorso, ti interessa
                    timer1.Enabled = true; // visualizza il tempo
                                           // mentre Worker carica il testo in modo asincrono
                                           // il programma non è bloccato, e può eseguire altre operazioni
                                           // l'evento Worker_RunWorkerCompleted si attiva quando il compito
                                           // di caricamento è terminato, e lì ci sarà il codice che serve per
                                           // notificare al resto del programma che il testo è disponibile
                }
            }
    
            private void Worker_DoWork(object sender, DoWorkEventArgs e) // ti interessa
            {
                // in e.Result si può restituire qualsiasi oggetto, io restituisco un testo
                // in e.Argument c'è l'argomento passato da: Worker.RunWorkerAsync(PercorsoDelFile); eseguo la conversione di tipo con (string)
                TESTOletto = File.ReadAllLines((string)e.Argument, System.Text.Encoding.UTF8).ToList(); // legge il file dal percorso in e.Argument, ti interessa
                e.Result = "Lette n. " + TESTOletto.Count.ToString("#,#") + " righe da: " + (string)e.Argument; // restituisco una stringa leggibile in Worker_RunWorkerCompleted, ti interessa
            }
    
            private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) // ti interessa
            {
                timer1.Enabled = false; // file caricato
                richTextBox1.Text = (string)e.Result; // mostro cosa ha restituito Worker in Result, eseguo la conversione di tipo con (string)
                hScrollBar1.Maximum = TESTOletto.Count - 1;
                hScrollBar1.Minimum = 0;
                Label1.Visible = false;
            }
    
            private void Timer1_Tick(object sender, EventArgs e)
            {
                // esecuzione mentre Worker lavora in background, ma si potrebbe fare anche altro
                richTextBox1.Text = "Lettura da file in corso " + StWa.ElapsedMilliseconds + " ms. " + Cx[n];
                if (n > 2) n = 0; else n++;
                Label1.Visible = !Label1.Visible;
            }
    
            private void HScrollBar1_Scroll(object sender, ScrollEventArgs e)
            {
                // se muovi la scrollbar, visualizzo una riga del testo caricato
                richTextBox1.Text = TESTOletto[hScrollBar1.Value];
            }
        }
    }
    
  • Re: Async await

    Mi sono appena resto conto che il mio ultimo ringraziamento non è stato pubblicato. stavo con il cellulare. Meglio così era troppo mieloso.
    però faccio il riassunto.

    anche se siete andati OT
    conservo gelosamente ogni vostro CONSIGLIO/SUGGERIMENTO.

    e mi viene in mente un post passato in cui, non ricordo chi, disse più o meno che, "imparare la musica era più facile che imparare a programmare"

    chissà forse adesso saprei suonare la chitarra... mentre oggi dalle liste sono passato alle Dictionary e mi fa già male la testa... e sono solo all'inizio.

    ogni vostro input è motivo di studio. Siete l'unico confronto che ho. e adesso non ricordo se questo pensiero già l'ho scritto.

    GRAZIE a tutti GRAZIE a Rubik GRAZIE a Alka GRAZIE ad Oregon GRAZIE GRAZIE GRAZIE.
  • Re: Async await

    Anche se in ritardo, e un po' disorientato, mi piacerebbe dare il mio contributo (anche se di basso livello):

    Credo che in realtà dovremmo sempre analizzare cosa deve fare il codice per poter rispondere in modo aderente alla richiesta. Se sto scrivendo una piccola utility, il cui unico compito è leggere un file, senza dover fare assolutamente nient'altro se non quello di attendere la lettura e l'elaborazione dei dati stessi, allora che senso ha far intervenire le operazioni asincrone, backgroundworker o thread multipli?
    Ci sarà sempre un modo più raffinato di fare la stessa cosa, ma io sono per semplificare.

    Pivello, ho visto che hai commentato Application.DoEvents() ... ma quello è ciò che ti permette di far elaborare i messaggi alla tua finestra o programma, facendo sì che non si blocchi.

    Per quanto riguarda la lettura di un file di dimensioni sconosciute in memoria, per poi elaborarlo, una delle scelte che si possono fare è quella di dividerlo in blocchi di dimensione massima definita in modo sia da accelerare l'elaborazione, sia da evitare l'eccessivo utilizzo di memoria o peggio.
    Se il file è più piccolo della dimensione massima del blocco verrà letto in una sola volta, altrimenti ci saranno n cicli di lettura elaborazione.

    Esempio:
    Se ho un file file da 102 Mb e decido che il blocco di memoria da utilizzare sarà di 10Mb allora il mio codice eseguirà 10 cicli di lettura ed elaborazione da 10 Mb ed uno da 2 Mb.
    In questo modo, possiamo anche ottimizzare inserendo due thread: uno di lettura ed uno di elaborazione.

    Spero di essere stato di aiuto.

    Claudio aka Dr. Shark.
  • Re: Async await

    drshark ha scritto:


    Se sto scrivendo una piccola utility, il cui unico compito è leggere un file, senza dover fare assolutamente nient'altro se non quello di attendere la lettura e l'elaborazione dei dati stessi, allora che senso ha far intervenire le operazioni asincrone, backgroundworker o thread multipli?
    Dipende dai requisiti. Per fare un paio di esempi, potrebbe subentrare la necessità di voler interrompere in qualsiasi momento il processo di lettura ed elaborazione del file, oppure ancora di svolgere parallelamente analisi di tipo complesso sui dati che vengono letti mano a mano dal file, che quindi conviene tenere slegati dall'operazione vera e propria di I/O.

    Nel caso in esame, credo che semplicemente l'uso sia finalizzato all'auto-apprendimento di nuove tecniche per padroneggiare meglio il framework e il linguaggio.

    Ciao!
  • Re: Async await

    Alka ha scritto:


    Dipende dai requisiti.
    Esatto! È quello che dico io. Spesso ci si incaponisce a voler fare qualcosa di "tecnicamente" ineccepibile, con l'unico risultato di perdere un sacco di tempo.
    Alcuni programmatori si sentono in colpa ad utilizzare il DoEvents ... troppo VB6 like

    Ovviamente se è per solo scopo di studio ... va provato tutto! Anche l'impossibile
  • Re: Async await

    drshark ha scritto:


    Alka ha scritto:


    Dipende dai requisiti.
    Esatto! È quello che dico io. Spesso ci si incaponisce a voler fare qualcosa di "tecnicamente" ineccepibile, con l'unico risultato di perdere un sacco di tempo.
    Alcuni programmatori si sentono in colpa ad utilizzare il DoEvents ... troppo VB6 like

    Ovviamente se è per solo scopo di studio ... va provato tutto! Anche l'impossibile
    Bisogna separare quando si programma per imparare e quando si programma in un team che sviluppa un progetto condiviso.
    Quando si impara, si prova tutto, si riscrive tutto, pur di capire o rendere più efficiente un codice anche se inutilmente.
    Quando imparo, voglio sapere di quanto stringbuilder è più efficiente, lo so che se concateno due strighe da 10 caratteri con + concat o stringbuilder, non ho dei vantaggi concreti ad usare una o l'altra tipologia, ma li testo lo stesso perché voglio essere pronto quando ne avrò bisogno.
    Quando si programma in team, se ineccepibile significa che il tuo codice è più leggibile perché rispecchia l'oop e i concetti di fondo del linguaggio, non significa che uno si "incaponisce", significa che uno vuole restare nel team.
    DoEvents esiste e non è antagonista di async await o backgroundworker.
  • Re: Async await

    Rubik ha scritto:


    Bisogna separare quando si programma per imparare e quando si programma in un team che sviluppa un progetto condiviso.
    Quando si impara, si prova tutto, si riscrive tutto, pur di capire o rendere più efficiente un codice anche se inutilmente.
    Quando imparo, voglio sapere di quanto stringbuilder è più efficiente, lo so che se concateno due strighe da 10 caratteri con + concat o stringbuilder, non ho dei vantaggi concreti ad usare una o l'altra tipologia, ma li testo lo stesso perché voglio essere pronto quando ne avrò bisogno.
    Quanda si programma in team, se ineccepibile significa che il tuo codice è più leggibile perché rispecchia l'oop e i concetti di fondo del linguaggio, non significa che uno si "incaponisce", significa che uno vuole restare nel team.
    DoEvents esiste e non è antagonista di async await o backgroundworker.
    Non sono sicuro di aver capito cosa vuoi dire, ma leggo un certo astio nella risposta. Non era mia intenzione offendere o mancare di rispetto e se l'ho fatto me ne scuso.

    Il mio discorso non era rivolto alle vs. risposte (ed è forse questo il punto) ma era un discorso generale. In realtà era una specie di risposta (ad una domanda non fatta) sul perché DoEvents venga "snobbato" da molti. Capisco che sarei dovuto essere più preciso nella mia risposta.

    I test li faccio anche io, sempre, anche per alcune cose che so già, ma su cui sono incerto.

    Ciao,
    Dr. Shark.
  • Re: Async await

    drshark ha scritto:


    Non sono sicuro di aver capito cosa vuoi dire, ma leggo un certo astio nella risposta. Non era mia intenzione offendere o mancare di rispetto e se l'ho fatto me ne scuso.
    Nessun astio, purtroppo la scrittura non mostra gli stati d'animo...
    Quello che ho scritto significa solo quello che ho scritto, se non cerchi tra le righe vedrai che è chiaro, o no?
  • Re: Async await

    Vi ho pensato spesso. Lo so è passato più di un anno da quando vi infastidivo. Era da tanto che non mi collegavo. E stasera l'ho fatto perchè volevo scrivere un post nel forum "bar". non mi ricordo nemmeno più come si chiama. E ho letto gli ultimi messaggi che non avevo letto. Infatti. La mia testardaggine serviva a imparare. Ricordo la prima sera che venni qui perchè non riuscivo a far girare 5 righe di codice compreso il for per colpa di un punto e virgola. Una nottata intera.
    E grazie alla vostra pazienza adesso (mi considero ancora un pivello) riesco a capire gli errori. e arrangiarmi da solo.
    Certo mi manca l'esperienza di un team. Come hobbysta solitario non so se quello che sto facendo è giusto. Sicuramente il mio codice è sporco. Ma almeno è servito a farmi staccare la spina dallo schifo di quest'ultimo anno.
    Se non fosse virtuale questo bar, stasera avrei offerto a tutti quelli presenti un giro... ma anche 2 di birra.

    GRAZIE. davvero. GRAZIE per il tempo che dedicate agli altri.
    Io "ero" un sanitario, e so che certe cose le si fanno senza aspettarsi nulla in cambio. E a volte qualche paziente riusciva a riscaldarmi il cuore. Lo so che queste sere sta iniziando a fare caldo. Ma quello che vorrei adesso e farvi sentire quel senso di gratificazione che a volte provavo quando qualcuno mi ringraziava. Certo non tutti. Ci sono diversi tipi di GRAZIE.

    E adesso smetto altrimenti non ricordo chi tra i senior si lamenterà con me di essere troppo mieloso. Mi sembra Alka.

    GRAZIE A TUTTI
  • Re: Async await

    Pivello ha scritto:


    Per me ogni risposta che mi date è importante.
    Anche quella di Rubik.
    Mi aiutate a capire come posso fare diversamente.
    Faccio un lavoro che non centra niente con la programmazione e l'informatica. L'età e il tempo che riesco a "rubare" non mi aiutano.
    E voi siete l'unico "confronto/riscontro" che ho.
    E grazie soprattutto a voi posso fare esperienza.
    Sono i vostri input che mi danno la voglia di cercare altro.
    Ogni vostra risposta la conservo gelosamente. E all'occorrenza vado a rileggerla.
    E adesso smetto, prima che Alka mi cazzea

    GRAZIE... sempre GRAZIE a TUTTI.
    il tempo passa ma i sentimenti restano
    e Alka scusa, per stasera perdonami
  • Re: Async await

    Rubik ha scritto:



    Metti in un colpo solo tutto il file in una lista, e poi esegui le operazioni sulla lista, la velocità si incrementerà di migliaia di volte.
    per dichiarare una lista di nome TESTOletto:
    
    private List<string> TESTOletto = new List<string>();
    
    per caricare nella lista un file testo in un colpo solo:
    
    TESTOletto = File.ReadAllLines(percorsoFile).ToList(); // legge il file testo
    
    ora puoi lavorare riga per riga il testo che è in ram, ogni riga ha il suo indice
    HO TROVATO LA DOMANDA
    cercando nel forum ho trovato questa vecchia richiesta di aiuto (sempre fatta da me )

    LA DOMANDA:
    private void leggiDictionary()
            {
                string rigo;
                foreach (KeyValuePair<int,int> kv in ordini)
                {
                    rigo= (kv.Key.ToString()+"\t"+kv.Value.ToString()+"\r\n");
                    richTextBox.Text += rigo;
                }
            }
    è un modo corretto per caricare la richTeXBox ?
  • Re: Async await

    LA DOMANDA:
    private void leggiDictionary()
            {
                string rigo;
                foreach (KeyValuePair<int,int> kv in ordini)
                {
                    rigo= (kv.Key.ToString()+"\t"+kv.Value.ToString()+"\r\n");
                    richTextBox.Text += rigo;
                }
            }
    è un modo corretto per caricare la richTeXBox ?
    [/quote]

    in questo caso la dictionary è caricata da un file. quindi per riempire la richTextBox, sicuramente l'ideale è caricare il file con il metodo LoadFile.
    ma la domanda "è un modo corretto per caricare la richTeXBox ?" vorrei lasciarla sempre per imparare altri modi.

    Grazie a tutti.
  • Re: Async await

    Pivello ha scritto:



    ma la domanda "è un modo corretto per caricare la richTeXBox ?" vorrei lasciarla sempre per imparare altri modi.
    al posto di richTextBox.Text += rigo;
    basta sostituire? richTextBox.AppendText(rigo);
  • Re: Async await

    Pivello ha scritto:


    al posto di richTextBox.Text += rigo;
    basta sostituire? richTextBox.AppendText(rigo);
    Sono equivalenti, la seconda forse è più veloce, ma si noterebbe solo con testi lunghi.
    Per imparare DEVI provare tutto, VisualStudio ti dice quanto tempo impiega ad essere eseguita un'istruzione.

    Nello spazio dei nomi System.Diagnostics; c'è l'oggetto Stopwatch che ti mostra quanto tempo è trascorso tra due punti di codice, utile per verificarne l'efficienza.

    per usare lo spazio dei nomi:
    using System.Diagnostics;
    per instanziare l'oggetto:
    
    Stopwatch sw = new Stopwatch();
    
    Per inizializzare l'orologio:
    sw.Restart();
    Per leggere il tempo trascorso e trasformarlo in una striga visualizzabile su una labe o dove vuoi:
    string tempo = sw.ElapsedMilliseconds.ToString("Time 000 ms")
    In questo messaggio avevo postato un codice che controlla anche la sua efficienza:

    Rubik ha scritto:


  • Re: Async await

    Pivello ha scritto:


    è un modo corretto per caricare la richTeXBox ?
    Perché hai risollevato questa discussione per trattare un problema di cui stai già parlando in questa discussione?

    Non è così che si usa un forum: per ogni problema, una sola discussione.

    Peraltro qui c'è il titolo "Async await" che non ha praticamente nulla a che vedere con la problematica che hai reintrodotto alla fine.

    In secondo luogo, continui a parlare di caricare testo in una RichTextBox ma - aneddotti non richiesti a parte - sia in questo contesto che nell' non è chiaro qual è l'alternativa che vorresti implementare (velocizzare il caricamento? usare un altro controllo per mostrare i dati? altro??).

    In breve, ci sono due discussioni di cui una fuori tema che espongono un problema non chiaro a cui hai replicato senza rispondere alle domande precise che ti sono state fatte nel contesto e senza indicare qual è l'obiettivo che stai perseguendo o l'errore, il problema o il comportamento anomalo che vorresti migliorare in un software che nessuno conosce e che carica dati in un formato non precisato.
Devi accedere o registrarti per scrivere nel forum
31 risposte