Problem mit Dispatcher und Invoke

25/02/2009 - 13:51 von Dietmar | Report spam
Hallo NG,

mir ist gerade ein Problem aufgefallen, das mir nun ziemliche Kopfschmerzen bereitet.
Bei Windows.Forms-Projekten verwende ich immer ISynchronizeInvoke,
um EventHandler garantiert im richtigen Thread aufzurufen.

Bei WPF mache ich das nun immer über den Dispatcher,
wie in anschliessendem Codebeispiel (Window1.xaml.cs, zum nachvollziehen C&P in ein neues, leeres WPF-Projekt "DispatcherTest").

Mein Problem dabei ist: solange ich nur einen EventHandler registriere, funktioniert alles wunderbar.
Registriere ich allerdings 2 EventHandler, wird JEDER zweimal aufgerufen.
Sind es 3 EventHandler, wird JEDER dreimal aufgerufen, ...

SingleStep durch OnMyEvent ergibt, dass jeder Handler einmal Invoked wird, tatsàchlich aufgerufen
werden sie aber wie im letzten Absatz beschrieben.

Verstehe ich hier grundsàtzlich etwas falsch und dieses Verhalten ist gewünscht oder
mache ich irgendwo einen Fehler?
Oder ist das wieder mal ein Fall für Connect?



MfG Dietmar



using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DispatcherTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
event EventHandler<EventArgs> MyEvent;

public Window1()
{
InitializeComponent();
MyEvent += new EventHandler<EventArgs>(Window1_MyEvent);
MyEvent += new EventHandler<EventArgs>(Window1_My2ndEvent);
MyEvent += new EventHandler<EventArgs>(Window1_My3rdEvent);
OnMyEvent();
}

void Window1_My3rdEvent(object sender, EventArgs e)
{
}
void Window1_My2ndEvent(object sender, EventArgs e)
{
}
void Window1_MyEvent(object sender, EventArgs e)
{
}
void OnMyEvent()
{
if (MyEvent != null)
{
EventHandler<EventArgs> handler = MyEvent;
foreach (EventHandler<EventArgs> h in handler.GetInvocationList())
{
System.Windows.Controls.Control c = h.Target as System.Windows.Controls.Control;

if (c != null
&& c.Dispatcher != null)
{
c.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new EventHandler<EventArgs>(MyEvent), this, new object[] { new EventArgs() });
}
else
{
h(this, new EventArgs());
}
}
}
}
}
}
 

Lesen sie die antworten

#1 Elmar Boye
25/02/2009 - 16:06 | Warnen spam
Hallo Dietmar,

Dietmar schrieb:
Bei WPF mache ich das nun immer über den Dispatcher,
wie in anschliessendem Codebeispiel (Window1.xaml.cs, zum nachvollziehen
C&P in ein neues, leeres WPF-Projekt "DispatcherTest").

Mein Problem dabei ist: solange ich nur einen EventHandler registriere,
funktioniert alles wunderbar.
Registriere ich allerdings 2 EventHandler, wird JEDER zweimal aufgerufen.
Sind es 3 EventHandler, wird JEDER dreimal aufgerufen, ...

foreach (EventHandler<EventArgs> h in handler.GetInvocationList())
...
c.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,



Ist irgendwo logisch da Du hier:

new EventHandler<EventArgs>(MyEvent),



MyEvent und damit dessen InvocationList - übergibst.

this,
new object[] { new EventArgs() });



Wenn Du "h" verwendest, so wird es nur einmal aufgerufen.

Gruß Elmar

Ähnliche fragen