Autor Beitrag
meisse
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Fr 08.07.11 14:49 
Hallo zusammen

In der CSharp Software werden Daten über einen Stream angefordert (gSOAP). Um mit gSOAP zu kommunizieren, haben wir eine C++ DLL dazwischen.
Aus der CSharp Software wird dann festgelet, was für Daten angefrodert werden. Man kann auch die Buffergrösse des Streams varrieren.
Ist die Anfrage mal abgesetzt worden, übernimmt die C++ DLL die Arbeit, um die Daten via SOAP anzufrodern. Dabei werden dann immer etwa Packete
von 64k von der C++ DLL via CALLBACK Funktion an die CSharp Applikation zurückgeliefert. Dabei muss dann in der CALLBACK Funktion die Daten vom
unmanaged Heap in den Managed Heap kopiert werden, um danach diese in ein FIFO zu speichern, welche dann weiter verarbeitet werden.

Nun das Problem: In der Callback Funktion werden die Daten in eine Queue (FIFO) geschrieben, und in einem anderen Thread dann wieder verarbeitet.
Nur teilweise passiert es, dass Daten, welche in der Callbackfunktion anstehen bis zu 3 sekunden benötigen um in die Queue zu gelangen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
public static void DispatchRawDataStream(IntPtr DataPtr, int DataLength) {
            watch.Start();
            Int32[] data = new Int32[DataLength];
            Marshal.Copy(DataPtr, data, 0, DataLength);


            lock (StreamQueueObj.lockObj) {
              StreamQueueObj.DataChunk.Enqueue(data);
            }

            watch.Stop();
            Console.WriteLine("DataLength: " + DataLength + " --> " + watch.ElapsedMilliseconds);
            watch.Reset();
            
        }


Also dort wo in der Console die ellapsed Zeit des Timers ausgegeben wird, dort kann es vorkommen dass wir zwischen 2-3 Sekunden warten müssen. Jetzt stellt sich
die Frage warum das so lange dauert? Beansprucht ein anderer Thread so lange Zeit ? Oder benötigt das kopieren aus dem unmanaged Heap teilweise so lange? Wenn ich die Zeiten betrachte dann, habe ich meistens 0 ms verzögerung, was auch anzunehmen ist... aber eben teilweise wartet die FUnktion 2-3 Sekunden.. Stellt sich vielleicht die Frage, auf welchem Thread der Callback ausgeführt wird? Kann ich dafür auch nen separaten Thread beanspruchen um solche Zeitkritischen Dinge zu entschärfen? Wenn ja wie ? Muss ich da von C++ DLL aus einen asynchronen methodenaufruf des Callbacks bewerkstelligen?

Mit freundlichen Grüssen
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 08.07.11 16:46 
Offensichtlich solltest du erst mal genauer rausfinden welcher Teil in der Methode lang dauert bzw. lange blockiert. Also Marshal.Copy oder dein lock oder der Enqueue(wenn es z.b. eine ConcurrentQueue<T> aus dem Framework lock die Methode auch nochmal) oder noch was ganz anderes. Sobald du herausgefunden hast woran es liegt kann man sich überlegen was man tun kann. Vorher wäre das nur Aktionismus ;)
meisse Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Mo 11.07.11 17:53 
Ich habe das ganze Problem ein wenig abgeschottet, indem ich die Daten zwar anfordere, aber den CALLBACK von der C++ DLL zurück in die CSharp Applikation unterbinde.
So werden die Daten vom gSOAP Server angefrodert und entsprechend an die C++ DLL weitergeleitet. Vom Server bis zur DLL gelangen die Daten sehr schnell (etwa 65 MB/s je nach Hardware).

Nun mein Hauptproblem liegt darin, diese Daten wiederum sehr schnell in eine HDF5 Datei zu speichern. Irgendwie is es nicht sehr elegant, die Daten in der Callback Methode in ein FIFO zu speichern, da der Speicherbedarf dadurch sehr schnell ansteigen kann, falls die Daten nicht genug schnell abgearbeitet werden. Ich suche darum nach eleganteren Methoden/Patterns um solche Datenmengen (Streams) zu verarbeiten ohne dass meine Applikation 500 MB Ram benötigt. Kann mir da jemand weitere Tipps geben?

Mit freundlichen Grüssen
norman2306
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 222
Erhaltene Danke: 16

Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
BeitragVerfasst: Di 12.07.11 07:51 
Wieso übergibts du nicht die Daten direkt als Byte-Array bzw. mittels Zeiger auf ein Byte-Array in der Callbackfunktion?