Laden...

Probleme bei der Threadsynchronisation+Performance Frage

Erstellt von expseeker vor 17 Jahren Letzter Beitrag vor 17 Jahren 1.396 Views
E
expseeker Themenstarter:in
9 Beiträge seit 2006
vor 17 Jahren
Probleme bei der Threadsynchronisation+Performance Frage

ich möchte die Perfomance meines Parsers verbessern.

Und zwar lese ich Daten mit 115200 baud über die serielle Schnittstelle ein.
Liegen daten am COM-Port an wird ein ReceiveEvent ausgelöst
Diese Daten werden von der COM Schnittstelle in einen byte Buffer geschrieben.

ich möchte danach die Daten verarbeiten (durchparsen,umrechnen etc)

der receive Event sieht so aus:


  private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
     
                
                int tempbuff = mycon.BytesToRead;
                if(buffer1inuse==true)
                mycon.Read(beit, workstreamsize, tempbuff);
                else
                mycon.Read(beit2, workstreamsize, tempbuff);
                workstreamsize += tempbuff;
                globalstreamcounter += tempbuff;

                if ((workstreamsize > 3500))
                {

                    
                    Streamsize = workstreamsize;
                    workstreamsize = 0;
                    buffer1inuse = !buffer1inuse;
                 //   newthreadexec = true;
                    OnBufferfullHand(new EventArgs());
                   
                }
}

Ich lese also die daten ein, ich möchte die Daten gleichzeitig einlesen und verarbeiten, daher nehem ich 2 Buffer her, in einem Buffer wird immer gelesen, der andere wird geparst. Ich löse dazu ein Event aus- wenn ein Buffer voll ist.

nun komme ich zu meinem Problem:

Ich habe einen zweiten Thread, der ja die Daten durchparsen soll.
Ich starte diesen Thread mit Thread Start, weiss aber nicht wie ich dem Threda sagen soll, dass er auf das event warten soll, und dann beginen soll,
nach dem er fertig gearbeitet hat, soll er wieder warten bis der event wieder ausgelöst wird.


 public void Bufferthreadfunc()
        {

           //     WAIT FOR SINGLE OBJECT(EVENT)?????

                current = DateTime.Now;
                //Logstream parsen

                if (buffer1inuse)
                    enddaten = parser(beit2);
                else //wenn buffer2 in use
                    enddaten = parser(beit);
                Logstream.Write(enddaten);


                if (running == true && globalstreamcounter > 64000)
                {
                    globalstreamcounter = 0;
                    Logstream.Flush();

                }
                if (Streamsize > 0)
                {
                    //unvollständige Pakete
                }

                
                Thread.Sleep(0);
                
          
                
           
        

        }

S
8.746 Beiträge seit 2005
vor 17 Jahren

Viel zu kompliziert:

Verschicke die Daten via Event (buffer.Clone() in Event-Args) und rufe den Event via BeginInvoke() auf. Fertig. Bevor du einen neuen Event verschickst, EndInvoke() auf dem Event aufrufen, so dass sichergestellt ist, dass die Verarbeitung des vorigen Aufrufes abgeschlossen ist.

1.378 Beiträge seit 2006
vor 17 Jahren

Vielleicht eine While Schleife in der du irgendeine allgemeine bool Variable abfragst ob sie True ist Wenn ja-> setzte auf falsch, und führ den Code aus.

T
73 Beiträge seit 2004
vor 17 Jahren

Hallo expseeker,

was du brauchst ist eine datenstruktur die von mehreren threads synchron lesend und schreibend benutzt werden kann. da ich gerade mit meinen studenten diese thema hatte möchte ich dir das nicht vorenthalten. wir haben eine queue die von einem netzwerkthread mit einkommenden paketen beliefert wird, also prinzipiell ähnlich wie bei dir. prinzipiell können dann n threads lesend auf diese queue zugreifen. dazu gibts im threading-namespace die monitor klasse. zum einstellen in die queue (oder eine beliebige andere collection)


		public void Enqueue(object val)
		{
			lock(_SyncRoot)
			{
				_Queue.Enqueue(val);
				Monitor.PulseAll(_SyncRoot);
			}
		}

und das auslesen


		public bool Dequeue(out object data)
		{
			bool result = false;
			
			lock(_SyncRoot)
			{
				//Check if queue empty...
				if(_Queue.Count == 0)
				{
					data = null;
				}
				else
				{
					data = _Queue.Dequeue();
					result = true;
				}
				
				Monitor.PulseAll(_SyncRoot);
			}
			
			return result;
		}

liefert true oder false wenn der puffer leer ist. das datum steht in data.
hab dazu eine komplett fertige demo & kann dir das zip gerne mailen!

-TS