Autor Beitrag
haschme
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 55
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.01.20 11:38 
Hallo zusammen,

ich würde gerne eine größere Datei einlesen und nach erreichen von Zeile 200 ein Datenpaket (aus den 200 eingelesenen Zeilen) an einen Webservice zur Verarbeitung schicken.
Um das ganze etwas zu beschleunigen möchte ich dazu mehrere Threads starten die sich dann parallel jeweils die nächsten 200 Zeilen für ein neues Datenpacket holen und an den Service schicken.
Die Datei die ich einlese ist in dem Fall eine CSV-Datei.
Als Neuling in dem Bereich "Parallelisierung" kam mir zunächst die TaskFactory am attraktivsten vor.
Damit habe ich auch schon etwas herumprobiert, was zu guter Letzt in so etwas endete:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
while(!reader.EndOfStream)
{
DataRecordCollection[] dataRecords1=null;
DataRecordCollection[] dataRecords2=null;

dataRecords1 = reader.GetNextRecords(200);
if(!reader.EndOfStream)
dataRecords2 = reader.GetNextRecords(200);

       recordsCount += dataRecords1.Length;
       recordsCount += dataRecords2 == null ? 0 : dataRecords2.Length;

       List <WebserviceResult> checkResults1 =null;
       List <WebserviceResult> checkResults2 =null;


        Task.Factory.StartNew(() => {
            if (dataRecords1 != null && dataRecords1.Length > 0)
            {
              checkResults1 = WebService.CheckRecords(dataRecords1);
            }
        }),
        Task.Factory.StartNew(() => {
            if (dataRecords2 != null && dataRecords2.Length > 0)
            {
              checkResults2 = Webservice.CheckRecords(dataRecords2);
            }
            return checkResults2;
        })
     };

      for (int i = 0; i < taskArray.Length; ++i)
      {
         if (i == 0 && taskArray[i] != null)
             checkResults1 = taskArray[i].Result;
         else if (i == 1 && taskArray[i] != null)
             checkResults2 = taskArray[i].Result;
  }

      //….. DO Something With the Results….

}


Im Prinzip versuche ich zunächst sehr simpel 2 Tasks zu erstellen die das gleiche machen sollen nur eben mit unterschiedlichen Datenpacketen (im Code dataRecords1 und dataRecords2)
Im ersten Durchlauf würde dataRecords1 die Zeilen 1-200 aus der CSV-Datei verarbeiten und an den WEbservice senden, dataRecords2 die nächsten 200 (201-400).
So wie mein Code dort werden die Webserviceanfragen ja auch schon parallel gesendet, nur stört es mich etwas, dass in der unterseten for-Schleife ja im Prinzip wieder auf beide Ergebnisse gewartet wird bevor es wieder weiter geht. Gleiches Problem hätte ich ja auch wenn ich "Task.Factory.ContinueWhenAll()" verwenden würde.
Besser wäre es wenn sobald ein Task mit seinem Datenpaket durch ist, es sich direkt das nächste Paket holt egal wie weit der andere Task gerade ist.
Das ganze habe ich auch schon einmal mit ContinueWhenAny() ausprobiert. Dort hatte ich allerdings dann das Problem, dass die Task´s fast gleichzeitig auf die selbe Datei zugreifen wollen um die neuen Datenpakete zu lesen.

Lange Rede kurzer Sinn: "Ich stehe auf dem Schlauch und währe sehr dankbar wenn der ein oder andere hilfreiche Tipps für mich hat" :-)

Viele Grüße,
Max
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4297
Erhaltene Danke: 924

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Fr 10.01.20 14:55 
Hallo,

dein Code kann so gar nicht fehlerfrei funktionieren, da du per Task.Factory.StartNew() neue Tasks startest, ohne auf deren Abarbeitung zu warten (oder wo werden die taskArray-Einträge gesetzt?).

Lese dich am besten mal in das Producer-Consumer-Pattern ein, z.B.
- Vorgehensweise: Implementieren eines Producer-Consumer-Musters
- The Producer Consumer Pattern in .NET (C#)
- TPL: Producer Consumer Pattern - Thread Safe Queue Collection

Für diesen Beitrag haben gedankt: haschme