Cerca su HostingTalk.it(puoi inserire qualsiasi parola, termine, azienda, espressione). Scrivi e premi INVIO!
Loading

+ Rispondi alla Discussione
Pagina 1 di 2 12 UltimaUltima
Risultati da 1 a 15 di 22

Discussione: Stranezza in C#

  1. #1
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Stranezza in C#

    Sto facendo una stupidaggine in C#, giusto per provare (non sembra male come linguaggio).

    Si verifica, però, una cosa strana:

    Codice:
    using (WebClient webclient = new WebClient())
    {
       ... un po di codice ...
    
       webclientHandler webclientHandler = new webclientHandler();
       webclientHandler.lista = listView;
       webclientHandler.nomeItem = item.Name;
    
       webclient.DownloadProgressChanged += webclientHandler.DownloadProgressChanged;
    
       ... altro codice ...
    }
    in pratica, creo un oggetto webclient e creo un oggetto webclientHandler al quale attacco alcuni miei settaggi.
    Poi passo il metodo "DownloadProgresChanged" di webclientHandler a webclient.DownloadProgressChanged.
    In sostanza, attacco un mio metodo ad un evento predefinito di .NET

    Tutto il codice di cui sopra è dentro un ciclo, che legge determinati valori e crea tanti oggetti per ciascun valore (ad esempio il download di 3 file)

    La stranezza è questa:
    se eseguo il codice così com'è, il download parte solo del primo file della lista, se invece introduco un banale ritardo (System.Threading.Thread.Sleep(5000) subito sopra la creazione dell'oggetto webclientHandler partono anche tutti gli altri download.

    E' come se, senza ritardo, non venissero creati nuovi oggetti.

    Che caspita può essere?
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.



  2. #2
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Mi sfugge qualcosa nel codice, prova a copiare le righe in cui richiami il metodo del webclient.

    Comunque visto così potrei pensare che l'esecuzione debba proseguire fuori dal blocco using, con lo sleep si dia tempo all'oggetto di entrare in una condizione tale da non poter essere cancellato/deallocato finito il blocco using.

  3. #3
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Il blocco using l'ho messo proprio per evitare possibili "riutilizzi" del mio oggetto (ovvero, la prima volta vien creato e la seconda in realtà viene utilizzato l'oggetto già esistente, nonostante il "new")

    Comunque sia, questo è il codice di tutto il bottone che esegue l'operazione:

    Codice:
                foreach (ListViewItem item in lstViewDownloads.Groups["paused"].Items)
                {
                    string nomefile = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString();
                    /*nomefile = nomefile = System.IO.Path.GetTempPath()+"prova.txt";*/
                    /*MessageBox.Show("Scarico in: " + nomefile);*/
    
                    /* Scarico tutti i file in sospeso */
                    WebClient webclient = new WebClient();
                    
                    Console.WriteLine("ID: {0}, download avviato.", item.Name);
                    /*System.Threading.Thread.Sleep(1000);*/
                    /*MessageBox.Show("itemName: " + item.Name);*/
                    webclientHandler webclientHandler = new webclientHandler();
                    webclientHandler.lstViewDownloads = lstViewDownloads;
                    webclientHandler.nomeFile = nomefile;
                    webclientHandler.nomeItem = item.Name;
                    webclientHandler.startTime = DateTime.Now;
    
                    webclient.DownloadFileCompleted += webclientHandler.DownloadFileCompleted;
                    webclient.DownloadProgressChanged += webclientHandler.DownloadProgressChanged;
                    webclient.DownloadFileAsync(new Uri(item.Text), nomefile);
                       
                    item.SubItems[1].Text = "Download in corso...";
    
                    webclientHandler = null;
                    webclient = null;
                    
                }
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  4. #4
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Se ho capito bene lo scopo è fare il download usando il metodo asincrono, il problema quindi è che la vita dell'oggetto non deve finire all'interno del ciclo.

    Con il blocco using viene chiamato un Dispose() sull'oggetto all'uscita, lo scopo dell'istruzione è anche quello, probabilmente senza sleep non faceva in tempo a partire il download perchè l'oggetto si distruggeva prima.

    Per le variabili dichiarate e il funzionamento in c# nei cicli non mi sono mai posto il problema, programmo principalmente in vb.net e li la variabile è sempre la stessa, cambia l'oggetto puntato.

    Comunque con l'uso di metodi asincroni l'oggetto va referenziato da qualche parte se no finito fuori dal suo scope il garbage collector prima o poi farà il suo lavoro e l'oggetto non ci sarà più.

    Potresti far puntare la proprietà Tag del ListViewItem a qualcosa che referezia poi sia il webclient sia il webclientHandler.

  5. #5
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Aspetta, forse ho omesso un particolare.
    Io ho una listview con al suo interno un certo numero di file da scaricare (il come ci arrivano dentro la listview, non ha importanza in questo discorso).

    Come puoi vedere dal ciclo (richiamato da dentro un bottone "Scarica") io faccio un foreach per ciascun elemento della listview e creo un oggetto WebClient avviando quindi il download.

    Creo un oggetto per ciascun file da scaricare e gli associo alcuni miei metodi in modo da monitorare lo status e la % di download.

    Potrei provare a creare un oggetto dal nome dinamico, anzichè riciclare sempre la stessa variabile. Ma come si fa?

    Come posso fare un "WebClient <nomedinamico> = new WebClient" ?

    E comunque, se fosse un problema di persistenza dell'oggetto, avrei un comportamento differente, ovvero lui parte con i download poi subito dopo lo ammazza avviando il nuovo. Io invece riesco ad avviare sempre il primo download (ed a completarlo) e mai il secondo, ovvero il nuovo oggetto o non viene creato oppure non viene eseguito.
    Al limite, con lo sleep riesco a far partire i primi due oggetti (ed a terminarne il download) ma mai un terzo, quindi non penso sia un problema di oggetti che si sovrascrivono, altrimenti il secondo download ucciderebbe il primo e gli monterebbe sopra.
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  6. #6
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Il problema è che quando la variabile è riutilizzata, il vecchio oggetto continua a esistere solo se è referenziato da qualche altra variabile, nel caso del webClient da quanto scrivi direi che se parte il download asincrono allora esiste fino alla fine.

    In conclusione vanno tenuti i riferimenti agli oggetti webClient e webclientHandler, perchè nel momento in cui non ci sono più variabili che puntano a loro sono destinati a essere distrutti.

    La prima idea che mi viene in mente è:
    - mettere nel webClientHandler un riferimento al webclient associato ad esempio con una variabile pubblica o una proprietà
    - utilizzare la proprietà Tag del ListViewItem per poi farla puntare all'oggetto webClientHandler
    - in base a come funziona questo webClientHandler mettergli un'eventuale proprietà che contenga il riferimento al ListViewItem nel caso debba accedere a questo oggetto.

    per fare poi qualcosa del tipo:

    Codice:
    WebClient webclient = new WebClient();
    webclientHandler webclientHandler = new webclientHandler();
    
    ....
    
    webclientHandler.webClientAssociato = webclient;
    webclientHandler.listViewItemAssociato = item;
    item.Tag = webclientHandler;
    
    webclient.DownloadFileCompleted += webclientHandler.DownloadFileCompleted;
    webclient.DownloadProgressChanged += webclientHandler.DownloadProgressChanged;
    webclient.DownloadFileAsync(new Uri(item.Text), nomefile);
    Il webClientHandler finito il download poi potrebbe togliere il suo stesso riferimento dal parametro Tag del listviewitem con listViewItemAssociato.Tag = null;

  7. #7
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Però facendo come dici te, ovvero usando il tag, potrei associare un solo webclient per volta e quindi un solo download per volta... io devo fare un download contemporaneo di una decina di file.
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  8. #8
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Il Tag è una proprietà del ListViewItem specifica dell'oggetto istanziato, quindi ogni elemento della lista avrà il suo Tag e così potrà avere associata una diversa coppia webClientHandler+webclient

    Edit: Tutto questo vale se stiamo parlando di questo ListViewItem: System.Windows.Forms.ListViewItem
    Ultima modifica di danielej; 17-08-2010 alle 00:31

  9. #9
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Quindi, in pratica, devo solo associare l'oggetto webclient ad un tag, in questo modo una volta avviati i download, posso anche uscire dalla funzione Click del bottone senza rischiare di ritrovarmi con oggetti latenti che sarebbero cestinati dal garbage collector perchè tali oggetti sono sempre referenziati in un tag della lista..

    boh, ci provo, è la prima volta che programmo in C# e non conosco bene .NET.
    Anni fa avevo ottime conoscenze di Visual Basic, ma poi ho lasciato perdere, saran 7-8 anni che non programmo in VB e .net ancora non esisteva. (usavo visual studio 6)
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  10. #10
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Non cambia niente, nemmeno con le tue variazioni.
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  11. #11
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    La cosa buffa è che nemmeno con i Thread si risolve.
    Usare i thread a questo livello è quasi banale, quindi ho fatto una prova, ma il risultato è lo stesso.

    Di interessante (forse) c'è il fatto che se tolgo l'async, ovvero forzo il download di tutto il file prima di proseguire con il resto del programma, non sempre il primo file della lista viene scaricato. Ad esempio in questa mia ultima prova, i primi due file li ha ignorati (nonostante sia stato creato il webclient, stando ad un log della console) ma il download parte (e quindi si blocca il programma, solo al terzo file).
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  12. #12
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Strano che dei download sincroni siano ignorati.

    Prova questo test come applicazione console, ora ho provato e qui mi partono solo 2 download contemporanei, gli altri download restano fermi finchè non si libera uno di questi 2 slot e a quel punto partono, alla fine tutti i file sono scaricati ma deve esserci qualche limite:

    Codice:
    using System;
    
    class Program
    {
        const string indirizzoDL = "http://prova/prova";
    
        static void Main(string[] args)
        {
            for (int i = 1; i <= 5; i++)
            {
                // avvio ciascun download in un thread differente
                System.Threading.Thread myStart = new System.Threading.Thread(myDL);
                // metto un nome personalizzato col numero
                myStart.Name = "Thread" + i;
                myStart.Start();
            }
            //questo per evitare che termini
            do
            {
                System.Threading.Thread.Sleep(1000);
            } while (true);
        }
    
        static void myDL()
        {
            try
            {
                System.Net.WebClient myWebClient = new System.Net.WebClient();
                string myDest = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
                string tName = System.Threading.Thread.CurrentThread.Name;
    
                Console.WriteLine(string.Format("{0:G} - {1} Iniziato", DateTime.Now, tName));
                myWebClient.DownloadFile(new System.Uri(indirizzoDL), myDest);
                Console.WriteLine(string.Format("{0:G} - {1} Completato - " + myDest, DateTime.Now, tName));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
    
        }
    
    }

  13. #13
    Provider L'avatar di danielej
    Data Registrazione
    Oct 2006
    Località
    Milano
    Messaggi
    504

    Re: Stranezza in C#

    Mistero forse svelato, il numero massimo di connessioni è limitato a 2 e si imposta con DefaultConnectionLimit di ServicePointManager, es.

    System.Net.ServicePointManager.DefaultConnectionLi mit = 10;

    Membri ServicePointManager (System.Net)

    C'è sempre da imparare

  14. #14
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Osta, mettendo a 10 in effetti partono più download contemporanei.
    Ma ne son partiti 4 nonostante in lista ne fossero presenti 6.
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

  15. #15
    Provider L'avatar di guest
    Data Registrazione
    Nov 2007
    Località
    Riccione
    Messaggi
    6,234

    Re: Stranezza in C#

    Scherzavo, ne parte sempre e solo 1.
    http://www.web4web.it - Low Cost Hosting
    Tutti i pacchetti sono multidominio.
    Database e domini illimitati a partire da €10


    http://www.guest.it - Servizi professionali su misura.

Discussioni Simili

  1. [Vendo] Dominio stranezza.com
    Di originalmi nel forum Domini e siti web: vendita, aste e acquisti
    Risposte: 0
    Ultimo Messaggio: 22-03-2010, 16:44
  2. Stranezza.. forse sono stato bucato?
    Di Fillo nel forum VPS - Virtual Private Server
    Risposte: 38
    Ultimo Messaggio: 27-04-2008, 13:26

Informazioni Discussione

Utenti che Stanno Visualizzando Questa Discussione

Ci sono attualmente 1 utenti che stanno visualizzando questa discussione. (0 utenti e 1 ospiti)

Tag per Questa Discussione

Segnalibri

Permessi di Scrittura

  • Tu non puoi inviare nuove discussioni
  • Tu non puoi inviare risposte
  • Tu non puoi inviare allegati
  • Tu non puoi modificare i tuoi messaggi