Avatar billede Syska Mester
19. januar 2009 - 18:17 Der er 10 kommentarer og
1 løsning

AsyncDownload en masse filer og fortsæt derefter main tråden

Hej,

Måske bare mig der ikke lige tænker logisk på sådan en mandag, men here goes ...

Jeg skal have hentet nogen filer som bliver opdateret hver dag ... fint nok, i starten hentede jeg dem, når jeg skulle bruge dem i mit problem. Men det tager jo lang tid når man skal hente dem en af gangen ...

Derfor så jeg at WebClient havde en AsyncDownload metode ... great ... jeg finder så ud af  hvor mange filer jeg skal have hentet og dividere det med 10 for at få et lidt fornuftigt tal at Async tråde jeg bør starte ...

Men hvordan får jeg det logisk bygget op på en smart måde så jeg kan blokere "main tråden" indtil jeg er færdig med at hente alle filer ... og så fortsætte derfra ...

Jeg har en implementering nu, men OMG, virkelig lort, så jeg leder lidt efter nogen gode ideer ... :-)

// ouT
Avatar billede arne_v Ekspert
19. januar 2009 - 18:24 #1
Jeg er ikke vildt begejstret for .NET aynsche API'er.

Hvad med at splitte dem der skal hentes op i N List<string> og så starte N tråde der
hver henter alt i en liste og i main tråden laver du bare Join på trådene.

Primitivt, men det bør virke.
Avatar billede Syska Mester
19. januar 2009 - 18:29 #2
ohhhh, det er jo faktisk ikke helt dumt ... jeg er heller ikke glad for dem, og synes nemlig også de har givet mig nogen problemer ...

Men det lyder som en god ide ...

Ville der være nogen problemer i at alle hentede et Item ud fra samme Liste, og fjernede det når de havde hentet det ... så kan jeg jo afsluttede tråedede når der ikke er flere Items i min liste ... ?

// ouT
Avatar billede arne_v Ekspert
19. januar 2009 - 18:43 #3
Det vill også virke, men du skal huske at synkronisere adgangen til listen (lock).
Avatar billede arne_v Ekspert
19. januar 2009 - 18:46 #4
Men så skulle det måske være en Queue og ikke en List.
Avatar billede Syska Mester
19. januar 2009 - 20:18 #5
Så det du faktisk siger er at jeg burde lave noget ala:
class ServerQueue<T> where T : class
{
    private Object thisLock = new Object();
    public Queue<T> f_Queue;

    public ServerQueue()
    {
        f_Queue = new Queue<T>();
    }
   
    public void Enqueue(T s)
    {
        f_Queue.Enqueue(s);
    }

    public T Dequeue()
    {
        if (f_Queue.Count == 0)
            return null;
        T s;
        lock (thisLock)
        {
            s = f_Queue.Dequeue();
        }
        return s;
    }
}
Avatar billede Syska Mester
19. januar 2009 - 22:01 #6
Det ser jo ud til at være ultraNICE ... :-) og virker skide godt ... og bedre end alt det Async crap.

Nu er alt delay væk jeg tidligere have og gør noget ala det her ...:
Har 3 lister ... alle thread safe med lock som overstående, dog også med lock i Enqueue, og så har den også fået en IsEmpty property.

1. Hvad der er ved at blive hentet
2. Hvad der mangler at blive hentet
3. Hvad der er hentet ...

kører så en while:
while(!DownloadList.IsEmpty || !ServerList.IsEmpty || !downloading.IsEmpty)
{
// get the Item from ServerList queue
// hvis man så trækker null ud af ServerList laver den et delay på 1 sek, og prøver igen ... for at se om der er komemt noget i ServerList ...
}

har du nogen kommentare til måden ? Hints og hvordan man måske hellere skulle lave det ?

Men i hvert fald må du gerne smide et svar ... blev lavet på en totalt lækker måde hvis man sammenligner med mit tidligere forsøg :-)

// ouT
Avatar billede arne_v Ekspert
19. januar 2009 - 23:51 #7
Dequeue er vist ikke thread safe !

        // her er der en tilbage
        if (f_Queue.Count == 0)
            return null;
        // her fjerner en anden tråd den sidste
        T s;
        lock (thisLock)
        {
            // hvad sker der here ?
            s = f_Queue.Dequeue();
        }
Avatar billede arne_v Ekspert
19. januar 2009 - 23:51 #8
Du skal have lock omkring både test og dequeue.
Avatar billede arne_v Ekspert
19. januar 2009 - 23:58 #9
Fra noget kode jeg lavede i sidste måned:

            bool done = false;
            do
            {
                MailJob mj = null;
                lock(q)
                {
                    if(q.Count > 0) {
                        mj = q.Dequeue();
                    }
                }
                if(mj != null)
                {
                    ...
                }
                else
                {
                    done = true;
                }
            }
            while(!done);
Avatar billede Syska Mester
20. januar 2009 - 01:31 #10
ohhh, det kan der selvf være noget om ... jeg fikser det.

Du må gerne smide et svar.
Avatar billede arne_v Ekspert
20. januar 2009 - 01:36 #11
kommer her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester