Autor Beitrag
florianreischer
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Di 13.10.09 13:23 
Hallo zusammen, ich habe einen merkwürdigen (o.g.) Fehler beim Aufrufen einer Anzeigefunktion in WPF. Aus einem Thread erhalte ich regelmäßig Daten die ich in der Oberfläche anzeigen will:

Mit dieser Zeile registriere ich den Listener für den Datengebenden Thread
ausblenden C#-Quelltext
1:
GpsService.Instance.GeographicCoordinateChanged += this.GpsService_GeographicCoordinateChanged;					


Hier werden die Daten im GuiThread abgefangen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
private void GpsService_GeographicCoordinateChanged(GeographicCoordinate coordinate)
{
   DisplayTextHandler handler = new DisplayTextHandler(this.DisplayGpsDeviceStatus);
   Dispatcher.Invoke(DispatcherPriority.Normal, handler, new object[] { coordinate.ToString(), Brushes.Black });
}


Das ist der Delegate für das Anzeigen von Texten:
ausblenden C#-Quelltext
1:
public delegate void DisplayTextHandler(string text, Brush textcolor);					


Und diese Funktion zeigt dann die Daten ohne cross-Thread Verletzung in der Gui an:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
private void DisplayGpsDeviceStatus(string text, Brush textcolor)
{
   this.txtDeviceStatus.Content = text;
   this.txtDeviceStatus.Foreground = textcolor;
}


Die Methode und der delegate passen zusammen, es wird ein string und ein brush erwartet. Im zweiten Codesnippet sieht man auch deutlich, dass ich zwei Parameter vorbereite und übergebe (Die Position und die Farbe des Textes). Dennoch erhalte ich beim Aufruf von Invoke folgende Exception.

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:
System.Reflection.TargetParameterCountException was unhandled
  Message="Parameter count mismatch."
  Source="mscorlib"
  StackTrace:
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Delegate.DynamicInvokeImpl(Object[] args)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at AloaMobile.App.Main() in E:\aloa\src\Aloa\AloaMobile\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:


Komischerweise poppt sie einfach so auf und hat keine Bindung zur Codezeile (Üblicherweise werden Exceptions beim debuggen in VisualStudio ja mit einer Zeile verknüpft). Das könnte aber evtl. an der Multithreadgeschichte hängen.. Hat jemand eine Idee woran es hier scheitern könnte?

Vielen Dank im voraus!
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 13.10.09 17:19 
Du musst schon die Überladung für mehrere Argumente benutzen:
ausblenden C#-Quelltext
1:
Dispatcher.Invoke(DispatcherPriority.Normal, handler, coordinate.ToString(), Brushes.Black)					

user profile iconflorianreischer hat folgendes geschrieben Zum zitierten Posting springen:
Komischerweise poppt sie einfach so auf und hat keine Bindung zur Codezeile (Üblicherweise werden Exceptions beim debuggen in VisualStudio ja mit einer Zeile verknüpft). Das könnte aber evtl. an der Multithreadgeschichte hängen..
Jupp. Der Mainthread wartet in der Nachrichtenschleife, bis er vom anderen Thread die Invoke-Nachricht bekommt und beim Abarbeiten die exception auslöst. Auf dem Callstack des Threads liegt dadurch noch gar kein Code von dir, also gibt es keine sinnvolle Codestelle zum Anzeigen.

PS: Wenn du auf Data-Binding + INotifyPropertyChanged setzt, nimmt dir WPF die gesamte Synchronisierung ab.

_________________
>λ=
florianreischer Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mi 14.10.09 08:45 
Ich habe das Schlüsselwort params übersehen und dachte ich muss ein object[] übergeben. Jetzt funktioniert es natürlich! Vielen Dank für den Hinweis. Das mit PropertyBindung und INotify.. werde ich mir noch anschauen! Vielen Dank