Autor Beitrag
Määx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 123



BeitragVerfasst: Fr 09.08.13 13:34 
Hallo zusammen,

ich habe ein kleines Programm, dass Messaging betreibt und anfangs zum teste das ganze wie folgt umgesetzt:
Die Main erzeugt eine Instanz der Empfängerklasse und aboniert dessen Events und beeinflusst dann via BeginInvoke die GUI. Dann habe ich später einen Manager hinzugefügt der das ganze übernimmt. Also habe ich bei Empfang eines Events aus der Main den Manager immer wie folgt aufgreufen:
ausblenden C#-Quelltext
1:
2:
3:
4:
BeginInvoke(new Action(() =>
            {
                __myManager.doAction(EventArgs);
            }), null);


Jetzt wollte ich den Empfänger direkt in den Manager legen um den Umweg über die Main zu ersparen. Der Manager erzeugt jetzt also eine Instanz des Empfängers und startet dessen Listener-Threads. Bei Ankunft einer neuen Nachricht wir ein Event ausgelöst und der Manager soll wie früher darauf reagieren. Also müsste ich hier ebenfalls ein BeginInvoke ausführen. Nur leider ist der "normalen Klasse" Manager diese Funktion nicht bekannt und im VisualStudio kann ich sie auch nicht auflösen lassen. Ist es hier nicht möglich eine solches Konstrukt laufen zu lassen und muss das immer über die Main gehen?

Sorry für die vll. dumme Frage...

Viele Grüße
Määx
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 09.08.13 13:45 
Invoke/BeginInvoke ist eine Feature von Winforms Control um ein spezielles Problem von UI Controls zu lösen wenn sie Threadübergreifend/asynchron angesprochen werden. Das macht in anderem Context keinen Sinn.

Wenn du einfach mehrere Threads hast die gemeinsame Resourcen haben und deren Zugriff synchronisiert werden muss dann solltest du die mit den Standardbordmitteln zur Threadsynchronisierung lösen. Dasn wären an erster Stelle locks. Wenn es komplexer wird dann Mutexe, Monitore WaitHandles, ReaderWriterLocks etc.
Määx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 123



BeitragVerfasst: Fr 09.08.13 13:55 
Hey,

ich spreche damit indirekt die UI an: Und zwar habe ich mehrere UserControls denen alle der Manager aus der Main übergeben wird. Je nach Message Events soll der Manager einige Aktionen durchführen und erzeugt dann wiederum diverse Events die an die UserControls gehen wo dann die UI threadübergreifend angepasst werden soll.

Da würden mir locks, Mutexe usw. nicht helfen oder?

Vielen Dank
Määx

Edit: also wenn ich das richtig verstehe läuft ja jedes ausgelöste Event in dem ListenerThread der Empfängerklasse. Somit läuft ja auch das ausgelöste Event im UserControl in dem Thread und hat keine Möglichkeit auf die GUI zuzugreifen? Oder habe ich da etwas falsch verstanden?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 09.08.13 15:18 
Die UserControls fangen Events vom Manager die nicht im UI Thread laufen? Dann muß im EventHandler des UserControls BeginInvoke des UserControls benutzt werden.

Für diesen Beitrag haben gedankt: Määx
Määx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 123



BeitragVerfasst: Fr 09.08.13 16:56 
oh nein, jetzt seh ich meinen Fehler!! Danke! Das hatte ich als erstes probiert, aber sinnloserweise in dem Presenter meines UserControls. Der kannte den BeginInvoke natürlich auch nicht...

Jetzt klappts! Vielen Dank!