Laden...

[erledigt] Brauche Hilfe bei TargetInvocationException

Erstellt von smilingbandit vor 16 Jahren Letzter Beitrag vor 16 Jahren 5.712 Views
S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 16 Jahren
[erledigt] Brauche Hilfe bei TargetInvocationException

Erklärung vorher:

Ich steuere zwei Geräte über eine serielle Schnittstelle an. Einen Barcodeleser und ein Messgerät.

Der Ablauf soll sein: Eine Messung wird durchgeführt, dann der Barcode des Geräts gescannt, und dann sollen die Daten gespeichert werden (Messprotokoll + Barcode).

Das mit dem Scanner habe ich über ein DataReceived-Event gelöst. Die Daten kommen an. Dann hab ich das ganze per BeginInvoke ins Form übernommen und lass es mir anzeigen. Funktioniert auch.

Das andere Gerät ist bischen kniffilger gewesen. Der Event ist in der Klasse zwar vorhanden, ich benutze ihn aber nicht, da ich das Ergebnis erst auslese (auslesen soll), wenn der Event des Barcodelesers gefeuert wird.

Weils zu Lesefehlern kommt (ohne Event) hab ich ein Tread.Sleep in die Lese-Methode gebaut. Nicht unbedingt elegant, aber naja. Hat funktioniert.

Warum ichs bei dem Gerät ohne Event gelöst habe:

Ich soll am Anfang herausfinden, an welchem COM es hängt. Löse ichs über ein Event, krieg ich als Ergebnis den Port, welcher genau einen Stelle im Array HINTER dem tatsächlichen Port ist (also z.b. an 17 gefunden, an 16 wäre korrekt).

Gut, nun zum Fehler selbst:

Wird das Event des Barcodelesers gefeuert, nimmt er den Barcode entgegen, die Methode startet danach das lesen des Messergebnisses, schickt sie an eine Klasse welche ihn Interpretiert, und am Ende geht das alles wieder in eine Klasse ums auf Platte zwischenzuspeichern.

Mein Verdacht, der sich so gut wie bestätigt hat:

Der StringWorker (der den Ergebnisstring in was brauchbares umwandelt) braucht zu lange, und zerschmeisst mir meine Applikation. Muss irgendwas mit dem Timing zu tun haben. Als ichs Schritt für Schritt verfolgt habe, ist der Fehler nicht aufgetreten (mit Haltepunkten etc.).

Was mich verwirrt ist, dass das vorher (ohne Event durch den Barcodeleser) funktioniert hat. Hat jemand irgendwelche Tips für mich, oder Anmerkungen/Lösungsansätze, bzw. kann mir wenigstens grundsätzlich sagen woher der Fehler kommen könnte?

Vielen Dank schonmal

edit: Die Fehlermeldung macht mich deswegen ratlos, weil er in die Main-Methode der Program.cs springt, wo die Form instanziiert wird.


System.Reflection.TargetInvocationException wurde nicht behandelt.
  Message="Ein Aufrufziel hat einen Ausnahmefehler verursacht."
  Source="mscorlib"
  StackTrace:
       bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       bei System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       bei System.Delegate.DynamicInvokeImpl(Object[] args)
       bei System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
       bei System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
       bei System.Threading.ExecutionContext.runTryCode(Object userData)
       bei System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup (TryCode code, CleanupCode backoutCode, Object userData)
       bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
       bei System.Windows.Forms.Control.InvokeMarshaledCallbacks()
       bei System.Windows.Forms.Control.WndProc(Message& m)
       bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       bei System.Windows.Forms.ContainerControl.WndProc(Message& m)
       bei System.Windows.Forms.Form.WndProc(Message& m)
       bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms .UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       bei System.Windows.Forms.Application.Run(Form mainForm)
       bei SecuTestEasyUse.Program.Main() in C:\Documents and Settings\hoepfoli\Desktop\Projects\SecuTestEasyUse\SecuTestEasyUse\Program.cs:Zeile 17.
       bei System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       bei System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       bei System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       bei System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ThreadHelper.ThreadStart()

G
497 Beiträge seit 2006
vor 16 Jahren

ich würde anstelle des Thread.Sleep() einfach ständig die Daten des Messgeräts entgegennehmen, den letzten gelesenen Wert irgendwo ablegen und dann auf diesen Wert zurückgreifen, sobald der Barcodescanner Daten geschickt hat. Könnte man mit einem Timestamp (der zusammen mit dem gemessenen Wert des Messgeräts aktualisiert wird) kombinieren, damit man sicher sein kann, daß die Daten zum Zeitpunkt des Scans passen und das Messgerät oder der dazugehörige Thread sich nicht zwischenzeitlich aufgehängt hat.

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 16 Jahren

Das hab ich auch mal implementiert. Nur wie gesagt, da kriege ich für das Gerät den falschen COM als Ergebnis, und das ist auch schlecht 🙂

edit: Was mich hauptsächlich interessieren würde wäre, warum es denn einwandfrei durchläuft, wenn ichs mit dem Debugger nachverfolge, aber ansonsten abbricht.

G
497 Beiträge seit 2006
vor 16 Jahren

im Debugger läufts eh alles etwas anders, vor allem bei Multithreading-Anwendungen. Schliesslich pfuschst du da ziemlich ins Timing und gerade da vermutest du ja dein Problem.

Was den COM-Port angeht: Hä?

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 16 Jahren

Zum COM:

Also is eigentlich recht einfach. Ich lass mir alle COMPorts liefern, und versuche zu jedem eine verbindung aufzubauen und einen Befehl hin zu schicken. Vom Messgerät erwarte ich eine bestimtme Antwort. Kommt die, dann hab ich den richtigen Port gefunden, und das ganze wird gespeichert.

Wenn ich das über die Events mache, dann liefert er mir den falschen COM, nämlich den im Array eins weiter stehenden.

U
1.688 Beiträge seit 2007
vor 16 Jahren

Wenn ich das über die Events mache, dann liefert er mir den falschen COM, nämlich den im Array eins weiter stehenden.

Dann addier' doch 'ne 1. Prinzipiell läuft ja der Eventhandler in Deinem Code und da kann nicht plötzlich was ganz anderes herauskommen. Also ist die Abweichung systematisch.

S
smilingbandit Themenstarter:in
151 Beiträge seit 2007
vor 16 Jahren

Ja ist sie, aber das war der letzte "dreckige" Hack den ich mir bis zum Schluss aufheben wollte 🙂

Das Problem ist (denke ich) gelöst. Und war an einer ganz anderen Stelle und hatte damit eigentlich gar nichts zu tun g

G
497 Beiträge seit 2006
vor 16 Jahren

Zum COM:

Also is eigentlich recht einfach. Ich lass mir alle COMPorts liefern, und versuche zu jedem eine verbindung aufzubauen und einen Befehl hin zu schicken. Vom Messgerät erwarte ich eine bestimtme Antwort. Kommt die, dann hab ich den richtigen Port gefunden, und das ganze wird gespeichert.

Wenn ich das über die Events mache, dann liefert er mir den falschen COM, nämlich den im Array eins weiter stehenden.

hört sich für mich an, als hättest du da ein kleines Logikproblem bei der Ermittlung des COM-Ports. Denn wenn du COM-Port X anfragst, geht die Anfrage auch dahin raus. Kann sein, daß du bei asynchroner Abfrage bereits den nächsten COM-Port abfragst, während die letzte Abfrage noch gar kein Timeout erhalten hat. Aber das kann man ohne Quellcode nicht sagen...

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo smilingbandit,

habe nicht den ganzen Thread gelesen, aber bei einer TargetInvocationException interessiert ausschließlich die InnerException. Wenn man die hat, hat man in der Regel alle Information, die man braucht.

Diesen Hinweis hättest du aber in der Zeit, in der du den langen Text geschrieben hast, auch über die Suche gefunden, zumal du mit TargetInvocationException ja ein sehr eindeutiges Suchwort gehabt hast.

herbivore