Avatar billede md_craig Nybegynder
26. maj 2006 - 20:59 Der er 14 kommentarer og
1 løsning

Gui Låser til trods for trådet program.

Hey eksperter...

Jeg har et lille "problem" jeg ville se om i kunne hjælpe mig med...

Jeg er i gang med at lave et lille framework til filoverførelse (etvejs PT)... jeg har så for at teste det lige lavet en lille GUI der gør jeg kan sende nogle filer... alt dettegår faktisk forbavsende godt... filerne bliver overført korekt og det hele...

Da der allerede er en hel del kode undlader jeg at poste kode her, istedet har jeg uploaded alt til:

http://code.dotjem.com/

Der er stadig meget kode som endnu ikke er "implementeret"...
Dette drejer sig primært om alle klasser som heder noget med "Comm" i starten, meningen er at disse skal bruges til commandoer... dette kører over en anden port således der bliver data socket og comm socket, der er ikke flere datasocket (som fx med ftp) da de data der skal overføres skal komme "synkront" eller hvad man skal sige... det skal ikke være nogen hemlighed at det skulle munde ud i at blive benyttet til MP3 streaming.

Serveren:

StreamServer.cs - http://code.dotjem.com/Server/StreamServer.cs.txt

Kører 2 tråde ved hjælp af delegates så det er threadpolled og med asunc callback når en tråd terminere. Det er PT kun en ene tråd, nemlig FileServer.... tråden som egentlig benyttes... tråden står og lytter på indkomne connections fra klienter, når det sker opretter den så en handler til en klient, denne er også trådet.

FileStreamClientHandler.cs - http://code.dotjem.com/Server/FileStreaming/FileStreamClientHandler.cs.txt

Det er så handleren, den kører som sagt i en tråd... handleren er den som står for at sende til en klient... dette gør den ud fra en Kø som indeholder de filer der skal sendes i form af en "Pakke" (FileStreamPackage.cs) som igen består af en header (FileStreamPackageHeader.cs) og data frames (FileStreamPackageFrame.cs).

Alle ligger i: http://code.dotjem.com/Server/FileStreaming/Packages/

Denne opdeling har noget at gøre med det fact at det er til streaming osv. vil jeg ikke gå så meget i dybden med med mindre der er spørgsmål til det. Desuden er der vist sket et lille knæk i navngivningen da Pakke måske burde have været det en frame nu er og det pakke nu er skulle bare være filen (ren forståelsesmessigt), men lad os nu ikke hænge os i det.

well... En Frame fra en Filpakke er angivet med ne størelse i byte som en ushort, en frame kan altså maximalt være 65kb. det FileStreamClientHandler.cs så gør er:

kigger på om klientens buffer er åben (denne funktionalitet er PT ikke implementeret, så klient bufferen er altid åben, dette har ikke noget at gøre med de buffere edr ligger i streamsne selv)...

Hvis den er det prøver den at sende data, når den starter på en ny fil sender den først en header og så begynder den at sende frames, en af gangen intil hele filen er overført (en frame har også en header)...

og det er faktisk her omkring det går galt...

jeg har nemlig måtte sætte en Thread.Sleep(10) ind mellem hver gang den skriver en frame, da den ellers låser den GUI som jeg bruger til at sende alle disse filer... en Thread.Sleep(10) fungere fint så længer framestørelsen ikke bliver for stor dog, gør den det låser den igen Gui og jeg må sætte Sleep størelsen op, men dette gør tilsyneladende overførelsen langsommere, og dette er jo ikke hensigtmessigt... (Man kan tydeligt mærke forskel på overførelseshastighed mellem fx 4Kb bloks og 65kb bloks)...

Nedsættelsen i hastigheden hænger jo naturligvis sammen med at der er den Thread.Sleep, da jo mindre frame størelse, betyder flere frames som igen betyder flere sleeps...

Derfor er blok størelsen uden den sleep forholdsvis irellevant (bortset fra at jo stører bloks, jomindre overhead er der)... men så låser gui... og med 10ms kan jeg ikke kommer meget højere end 4Kb så skal jeg øge sleep time, som så igen gør det langsomt...

Så spørgsmålet går på hvordan jeg lige håndtere denne situation...
Det er jo allerede trådet i stor stil... (og tråde der arbejder for meget kan jo godt virke blokerende, men burde ikke være så galt at jeg skal miste overførelses hastighed eller gui funktionalitet alt efter valg... :S)

HELP PLZ
Avatar billede sovsekoder Nybegynder
27. maj 2006 - 09:25 #1
kan du ikke uploade en zip med din solution ell. alle sourcefiler?
Avatar billede md_craig Nybegynder
27. maj 2006 - 09:51 #2
Det der ligger der er faktisk alle sourcefiler (tror jeg da nok)...
Havde lige glemt 2 klasser fra en 5. projekt...

Tror det er det hele...
Men de 2 filer er af relativ lille relevans vil jeg mene, men nu er de der også...

Så den komplenne kildekode skulle ligge der nu....
Ellers ved jeg ikke hvad du mener?
Avatar billede md_craig Nybegynder
27. maj 2006 - 09:59 #3
Og nu ligger solutionen der også...
Avatar billede sovsekoder Nybegynder
27. maj 2006 - 22:01 #4
har lige prøvet at køre dit program, jeg har ikke noget problem med GUI'en på serveren når jeg fjerner din Thread.Sleep(10) i FileStreamClientHandler.RunFileStreamClientHandler()
Avatar billede sovsekoder Nybegynder
27. maj 2006 - 22:01 #5
jeg har nok misforstået dit spørgsmål!? - du må skære problemet mere ud i pap.
Avatar billede sovsekoder Nybegynder
27. maj 2006 - 22:15 #6
du bør nok flytte din tråd fra threadpool'en for ikke at optage plads i threadpoolen. Threadpoolen bør bruges til kortvarige opgaver. - men det kan ikke være det der er problemet vil jeg mene.
Avatar billede md_craig Nybegynder
27. maj 2006 - 22:26 #7
Du skal prøve at åbne en fil, begynde at overføre den, så prøve at finde en ny fil at overfører... det er altså når tråden står og arbejder...

Ang. threadpoll, så er det faktisk lidt med vilje, sagen er at hvis der kommer 200+ klienter er der pluselig 200 tråde der vil arbejde samtidig hvis det ikke er polled threads, og det kan også dræbe serveren...

Eller det er hvertfald hvad jeg har lært af fageksperter ;)... har selv haft svært ved at arbejde med ensempler i størelser hvor jeg kunne se det ske...
Avatar billede md_craig Nybegynder
27. maj 2006 - 22:28 #8
og "låser" er måske også et hårdt ord, men sagen er at jeg næsten ikke kan nå at åbne en ny fil før den anden er overført fordi gui'en bliver utrolig sløv... :S
Avatar billede md_craig Nybegynder
27. maj 2006 - 22:44 #9
hehe... det kan være det slet ikke er serveren der gør det :P...

Noget jeg ikke lige havde tænkt på før var at se på CPU forbrug, og i det jeg sender filer så arbejder clienten med 90%... så vil lige tage en kigger på den ^^
Avatar billede sovsekoder Nybegynder
28. maj 2006 - 09:31 #10
ok.. nu har jeg ikke kigget særligt meget på din kode. Men spawner du ikke kun et par tråde i starten (en til at sende og en til at modtage)? - eller har du een tråd pr. klient?

Jeg vil nok anbefale at holde det til at minimum af tråde. Hvis du har brug for threadpool funktionalitet ville jeg nok selv implementere det for ikke at blokkere threadpool'en. Hvis du optager alle pladser i threadpool'en er der ikke plads til system funktionalitet der bliver lagt i threadpoolen.
Avatar billede sovsekoder Nybegynder
28. maj 2006 - 09:33 #11
...altså hvis det er langvariage operationer, som det måske godt kan blive hvis du overfører store mp3'er på en ikke så hurtig forbindelse..
Avatar billede md_craig Nybegynder
28. maj 2006 - 13:12 #12
Mja... sad lige og kiggede det igennem i går, kan godt være jeg skal til at implementere ThreadPooling selv, for jeg har en tråd til hver klient PT... Eller 1-X klienter pr. tråd... Må jeg lige lave lidt overvejelser om...

En MP3 må desuden MAX tage dens afspildnings tid (Og meget over halvdelen ville ikke være godt) at sende, ellers dør ideen med at det skal benyttes i forbindelse med streaming af MP3'er rimelig hårdt...

Derfor er der krav til forbindelsen i forhold ofc... (Det skal kunne kontinuerligt streame MP3'er, gerne i 192kbit, derfor vil en forbindelse der kan håndtere dette jo være minimum)...

Men må lige sætte mig lidt ind i hvordan jeg selv styrer Threads, og sætter dem i Thread pools mm. og hvordan jeg evt. styrer at de "kommer ind i varmen" i noget tid, og så "ud i kulden" selv om de egentlig ikke er færdige...

Havde jeg bare sådan lidt fået indtrykket at når man benyttede delegates, og man fik mange threads i sin pool, så blev de pillet lidt ind og ud, men hvis de ikke gør det, vil serveren dø efter der er 25 klienter på... (med standard max for ThreadPoolen)...

Derudover skal jeg have løst klientdelen, for det er 100% den der står og bruger så mange resourser at det bliver alt alt for sløvt at arbejde med serveren... så det skal implementeres på en anden måde... (har nemligt prøvet at smide den Thread.Sleep(10) ud så den "sover" for hver read opetarion, men når jeg kun læser en byte af gangen bliver det jo hurtigt 50.000.000 ms den tager om en fil (plus det det faktisk tager at læse osv.)

Og det bliver ca. 13 timer... må have fat i den hver gang den stream har buffered X anta bytes, og så læse dem på en gang, hvor X skal findes ud fra situationen, for prøvede med et fixed tal på et tidspunkt (1024)... og det syns jeg ikke jeg kunne få til at virke, så blokkede den så det ud til...
Avatar billede md_craig Nybegynder
28. maj 2006 - 18:36 #13
ok nu fik jeg vist lavet noget på klientsiden som gør at filoverførelsen både er hurtig samtidig med at klienten ikke kræver extreme resourcer...

således er det blevet til:

public void RunFileStreamClientReciever()
{
  int threshold = this.client.ReceiveBufferSize;
  Console.WriteLine("ReceiveBufferSize: " + threshold);
  while (this.run)
  {
    try
    {
      if (this.client.Available >= threshold)
      {
        byte[] tmp = new byte[threshold];
        this.streamReader.Read(tmp, 0, tmp.Length);
        this.buffer.Write(tmp);
        threshold = this.client.ReceiveBufferSize;
        Thread.Sleep(1);
      }
      else
      {
        threshold /= 2;
        Thread.Sleep(10);
      }
    }
    catch (Exception)
    {
      Thread.Sleep(10);
    }
  }
}

Altså, jeg starter med at kigge på hvad der ligger af data klar, er det mere end et givet treshhold, så læser jeg det venter 1ms og prøver at læse med det samme igen...

Hvis det ikke var det, så halvere jeg det treshhold den havde og venter 10ms (kan måske sættes op, eller relatere til den størelse treshhold har), før jeg prøver igen...

Hver gang jeg læser fra streamen, så resetter jeg treshold;
____________________________________________________

Så nu ligger serveren bare for at skulle gennemgå en heftig struktur ændring i trådene  .. Ved ikke helt hvordan jeg vil håndtere det endnu...

Ville være rart om jeg kunne have X antal tråde hvor jeg så via en handle kunne pille dem ind og ud af min ThreadPool... Således at når jeg måske havde 200 tråde til klienter, ville de på skift få lov at arbejde... men skal vist læse en masse om tråde før jeg lige griber alt for meget omkring det...
Avatar billede md_craig Nybegynder
29. maj 2006 - 18:20 #14
Og så gik han igang med sin egen ThreadPool klasse... Ohh lord...

enyways så fik jeg jo egentlig løst det oprindelige problem... men fik samtidig belyst et andet problem jo, hvilket jeg så vil dreje den lidt over på...

Vil gerne have indput fra folk med gode ideer til en threadpool... har selv 2 eksempler at gå ud fra fundet gennem:

http://www.eksperten.dk/spm/712191

Men 1 i VB og et andet som er MEGA uoverskueligt på stående fod...
Men nu må vi se... hvis nogen har noget at skyde ind så gør endelig :D
Avatar billede md_craig Nybegynder
17. august 2006 - 09:29 #15
nå jeg lukker her, der er vist ingen grund til at holde det åbent...

Threadpool spørgsmålet er flyttet.
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
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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