Hallo beisammen!
Wir entwickeln unsere Projekte in C für verschiedene Zielplattformen. Um ein Laufzeitsystem zu emulieren würden wir unser C-Projekt in einer C#-Desktop Umgebung einbetten (wollen). D.h. die HW-Schicht und Ein/Ausgabe würden wir uns emulieren (in C#), die Applikation wird in C (unverändert) eingebettet.
Hat das schon mal jemand gemacht? Kann ich in einer Projektmappe ein C-Projekt (z.B. als dll) in mein C#-Projekt einbinden und Compilerübergreifend debuggen? Oder steht mir dies nur per C und C++ per Visual Studio zur Verfügung?
Grüße,
gibt es eine Möglichkeit dies abzubrechen? Nach dem "Neuerstellen" bzw. bei Neustart der Applikation gibt es ja keine Probleme...
Folgende Frage wegen der Freigabe der Ressourcen:
an this.serialPort.Close(); hängt das Programm recht lang. Was kann man dagegen machen?
PS: bekomme durchgehend Daten (6byte alle 2-4ms)
Danke für die Antworten. Aktuell hat sich einiges verbessert indem ich
den StreamWriter
Encoding enc = Encoding.ASCII;
sWriter = new StreamWriter(path, false, enc, 2200);
fest konfiguriert habe und zusätzlich das Flushen selbst übernehme. Jetzt verliere ich nur noch wenige Daten.
Die Puffergröße habe ich mir wie folgt erreichnet:
63-68 Zeichen pro Zeile ~ 70
alle 30 Zeilen lasse ich ihn schreiben + 100 Puffer.
Bemerke per Performancecounter schon Veränderungen um eine ganze Stelle. Jedoch nur alle 4-20 Durchläufe. Hätte gedacht, dass dies durchs Threading kommt. Wie kann ich direkt abfragen, ob der GC aktiv ist?
Notfalls bleibt mir noch die Möglichkeit, direkt im CANRead Thread Strings zu basteln und diese in den Puffer für den Logger zu schieben.
Danke, Gruß
Hallo!
keine Antwort? Was für alternativen habe ich zum "Umschalten auf die anderen Threads"? Bin davon ausgegangen, dass ich mit Thread.Sleep(0) den aktuellen Thread die Ressourcen entziehe und ein anderer weiter arbeiten kann.?
mfg
okay, so siehts aus (etwas vereinfacht), falls was wichtiges zum Verständnis fehlt, einfach Bescheid sagen.
//Klasse CANHandler
public void startCANRead()
{
//config thread
CANReadThreadIsAlive = true;
CANReadThread = new Thread(CANReadData);
CANReadThread.Priority = ThreadPriority.BelowNormal;
//message counter
count = 0;
CANReadThread.Start();
}
private void CANReadData()
{
messagesReceived = 0;
messagesLost = -1;
Int64 s1=0, s2=0;
//Stopwatch stopWatch = new Stopwatch();
while (CANReadThreadIsAlive)
{
CanPort.CanEvent ev;
Object newMessage = new Object();
try
{
/* Read events until error */
while (pCAN.ReadEventData(out ev) == 0)
{
//...
//Nachrichten auslesen & in Arraylist schaufeln
//...
//breaking reading
if (!CANReadThreadIsAlive)
{
CANReadThreadIsAlive = false;
count = 0;
frmMain.Instance.ThreadStopped();
break;
}
}
Thread.Sleep(0);
}
catch
{
//empty, jump into, if CE message queue is empty (normal just a few ms)
Thread.Sleep(0);
}
/* Wait for next event */
if (pCAN.WaitCommEvent(out mask) != 0)
throw new CanPortException("Error in WaitCommEvent()");
}
}
public void stopCANRead()
{
CANReadThreadIsAlive = false;
count = 0;
//loggingStep = 0;
frmMain.Instance.ThreadStopped();
}
//Klasse Logger
public void startLogging(string folder)
{
//...
//file anlegen usw.
try
{
//...
//feste daten in file schreiben, fehler vermeiden usw.
if (isLogging)
{
//config thread
MessageLoggerThreadIsAlive = true;
MessageLoggerThread = new Thread(saveMessagesThread);
MessageLoggerThread.Priority = ThreadPriority.BelowNormal;
MessageLoggerThread.Start();
}
}
catch (Exception e)
{
//Fehler abfangen usw.
}
}
public void saveMessagesThread()
{
while (MessageLoggerThreadIsAlive)
{
if (messageQueue.getNumber() == 0)
Thread.Sleep(0);
else
saveMessage(messageQueue.get());
}
}
public void saveMessage(Object o)
{
//...
//Daten aus Objekten lesen und in asc file schreiben per Streamwirter
sWriter.Flush();
}
//Klasse MessageQueue
public class MessageQueue
{
public static readonly MessageQueue Instance = new MessageQueue();
private ArrayList list = new ArrayList();
private static Object mutex = "";
private MessageQueue () {}
public Object get()
{
Object o;
lock (mutex)
{
if (list.Count > 0)
{
o = list[0];
list.RemoveAt(0);
return o;
}
return null;
}
}
public void insert(Object o)
{
lock (mutex)
{
list.Add(o);
}
}
public int getNumber()
{
return list.Count;
}
}
Hallo!
Danke für die Antworten!
Hab jetzt mal alles etwas umdesignt, dennoch ändert sich nix. Jenachdem wie ich die Thread Priorität verdrehe, entweder läuft mein Puffer voll, oder ich verliere nachrichten, oder im worstcase ist die gui nicht mehr ansprechbar. hab den code etwas optimiert, nicht wirklich merkbar.
noch eine Frage bzw. dem Warten, habe bisher immer ein Thread.Sleep(0), wenn z.B. der CAN Treiber keine Nachrichten im Puffer hat. Ist das so sinnvoll?
mfg
Folgende Frage zur sauberen Synchronisation:
wollte eigentlich die Monitor Klasse in Verbindung mit locks verwenden. Natürlich wird jedoch die Wait, Pulse und PulseAll Methode nicht vom CF 2.0 unterstützt. Welche Alternativen habe ich da?
Ist das AutoResetEvent performant genug?
Danke, mfg
Hallo!
Folgendes Verständnisproblem:
Grundlage:
IST-Zustand:
=> Problem: Aufgrund der hohen Emfangsdichte der Nachrichten werden zu viele Nachrichten nicht abgeholt und somit verloren
SOLL-Konzept:
Ein weiterer Thread für das Logging (Erzeuer/Verbraucher) soll die Daten speichern. Bringt das was? Oder welcher Ansatz wäre zu empfehlen? Kann ich das Logging optimieren?
Danke, mfg
wie verhält sich das eigentlich performancetechnisch zwsichen dem überschreiben der onpaint-methode und das zeichnen auf der bitmap für die picturebox?