[C#] [Thread] Göra jobbet snabbare med flera på samma gång

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jul 2016

[C#] [Thread] Göra jobbet snabbare med flera på samma gång

Tja,

Har läge försök med detta det jag vill är att Göra flera trådar och skicka ut olika uppdrag till dom så att det går snabbare.

private Thread[] thread = new Thread[3];

Jag har en store lista som den ska hämta i från och sen söka i filen. mmm

string[] files = Directory.GetFiles("test", "*.txt"); foreach (string dir in files) { for (int i = 0; i < thread.Count(); i++) { if (thread[i] != null) { if (thread[i].IsAlive == false) { ThreadStart starter = delegate { cachesave(dir); }; thread[i] = new Thread(starter); thread[i].Start(); } } else { Console.WriteLine("error"); ThreadStart starter = delegate { cachesave(dir); }; thread[i] = new Thread(starter); } } }

Orginal koden är borta som jag gjorde så drog ihop detta lite snabbt för att visa er hur jag tänker och vad jag vill uppnå.

Problemet som jag får är att den kör samma text fil tre gånger och inte tar tre text filer på samma gång.

Man är inte dum för att man har stavproblem.
Läs mer om min synfel Visual Snow
Om mig ----> #16970666

Trädvy Permalänk
Medlem
Registrerad
Sep 2016

Titta på Tasks istället. Även om det går att få det där att fungera så blir det bara krångligare än att använda det som är inbyggt redan.

string[] files = Directory.GetFiles("test", "*.txt");
List<Task<bool>> tasks = new List<Task<bool>>();
foreach (string dir in files)
{
var task = Task.Run(() => cachesave(dir););
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());

Finns dock inget som säger att det absolut blir flera trådar parallellt utan man lämnar det till systemet att bestämma, kan bli en tråd upp till antalet cores men ingen garanti.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Okt 2012

Jag har använt mig av Parallel.For tidigare och det har fungerat bra. Här har du en tutorial.

Mvh
Hugo

Fractal Design Define R5 | Custom vattenkylning | Intel Core I5 3570K @ 4.4GHz | ASUS Sabertooth Z77 | Sapphire R9 Fury | 24 GB 1600MHz | Corsair RM 750x | Samsung 830 128 GB | Crucial BX100 500GB |

| Egenbyggd DAC: MINI4396, moddad | --> | Fostex TH-X00 |

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jul 2016
Skrivet av lrkss:

Titta på Tasks istället. Även om det går att få det där att fungera så blir det bara krångligare än att använda det som är inbyggt redan.

string[] files = Directory.GetFiles("test", "*.txt");
List<Task<bool>> tasks = new List<Task<bool>>();
foreach (string dir in files)
{
var task = Task.Run(() => cachesave(dir););
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());

Finns dock inget som säger att det absolut blir flera trådar parallellt utan man lämnar det till systemet att bestämma, kan bli en tråd upp till antalet cores men ingen garanti.

Den tog nästan död på min CPU runt 70-100 % xD

För den söker i ca 33k text filer så man måste ha någon limit?

Vad finns det för mer som man kan använda sig av finns så många?

Man är inte dum för att man har stavproblem.
Läs mer om min synfel Visual Snow
Om mig ----> #16970666

Trädvy Permalänk
Medlem
Registrerad
Sep 2016
Skrivet av superegg:

Den tog nästan död på min CPU runt 70-100 % xD

För den söker i ca 33k text filer så man måste ha någon limit?

Vad finns det för mer som man kan använda sig av finns så många?

Ajdå, ja det var mer ett snabbt exempel. Som det är skrivet där så kommer den starta lika många tasks som det finns filer. Vill man begränsa det så kan man räkna upp en counter i loopen och göra WaitAll på ett begränsat antal tasks i loopen, så att tex tre tasks skapas och sedan väntar man innan man skapar fler.

Annars är Parallel.ForEach framtagen just för att parallellisera iterationer så du kan pröva det istället.
http://stackoverflow.com/a/9290531

Trädvy Permalänk
Medlem
Plats
skåne
Registrerad
Apr 2010

ditt kodexempel loopar över alla dina trådar (den inre for-loopen) för varje fil i arrayen. därför får du samma textfil tre gånger.

kan du slippa mikromanagera trådarna så är det att föredra. till exempel som förslagen ovan. och 100 % cpu är väl inte dåligt om du inte måste ha den till något annat ;-). det innebär ju bara att det går snabbare om den har mer resurser att utnyttja.

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jul 2016
Skrivet av lrkss:

Ajdå, ja det var mer ett snabbt exempel. Som det är skrivet där så kommer den starta lika många tasks som det finns filer. Vill man begränsa det så kan man räkna upp en counter i loopen och göra WaitAll på ett begränsat antal tasks i loopen, så att tex tre tasks skapas och sedan väntar man innan man skapar fler.

Annars är Parallel.ForEach framtagen just för att parallellisera iterationer så du kan pröva det istället.
http://stackoverflow.com/a/9290531

List<Task> tasks = new List<Task>(); foreach (string dir in files) { var task = Task.Run(() => test(dir)); tasks.Add(task); if (tasks.Count() == 3) { Task.WaitAll(tasks.ToArray()); tasks.Clear(); } }

Vad tycker du om denna? Den verka funka bra än så läge.

Man är inte dum för att man har stavproblem.
Läs mer om min synfel Visual Snow
Om mig ----> #16970666

Trädvy Permalänk
Medlem
Registrerad
Sep 2016
Skrivet av superegg:

List<Task> tasks = new List<Task>(); foreach (string dir in files) { var task = Task.Run(() => test(dir)); tasks.Add(task); if (tasks.Count() == 3) { Task.WaitAll(tasks.ToArray()); tasks.Clear(); } }

Vad tycker du om denna? Den verka funka bra än så läge.

Ser bra ut. Finns status på Task också som du kanske vill kunna kolla, som IsFaulted och andra. Men det beror på, inte säkert du behöver göra det men bara så att du vet om det.

Du kanske också bör ha en WaitAll efter loopen också, om det blir en eller två tasks kvar beroende av antal filer.

Trädvy Permalänk
Medlem
Plats
Borlange
Registrerad
Okt 2007

@superegg: Prova nedanstående för att jobba med flera trådar:

var files = Directory.GetFiles("test", "*.txt").ToList(); Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (file) => { // gör något med file });