Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: C# und .NET ::  Zuviele Delegaten....     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
7x7-7
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.08.2009
Beiträge: 108
Beitrag 7x7-7 Mitglied 22:44:57 13.11.2017   Titel:   Zuviele Delegaten....            Zitieren

Hallo Forum,
ich habe in einer App viele Threads, die aus verschiedener Hardware Daten ziehen. Jetzt besitzt die App auch eine richtextBox, in welcher Meldungen aus diesen Threads angezeigt werden. Bisher habe ich dazu für jeden Thread einen eigenen Delegaten angelegt, der in etwas die folgende Form hat:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        public delegate void ControlStringConsumer(string text, int control);  
        public void SetText(string text, int control)
        {
            if (this.richTextBox1.InvokeRequired)
            {
                this.Invoke(new ControlStringConsumer(SetText), new object[] { text, control });  
            }
            else
            {
                switch (control)
                {
       
                    case 0: richTextBox1.Text = text + "\n" + richTextBox1.Text;
                        break;
                    case 1: richTextBox1.Text = "";
                        break;
                    default:
                        break;
                }
            }
 
        }


Da ich nun für jeden dieser Threads so eine Definition anlege – etwa SetText1, SetText2 usw., sammelt sich da viel Code an. Verwende ich den selben Delegaten für zwei asynchrone Threads, so kommt es natürlich zu einer Zugriffsverletzung, wenn beide Threads mal gleichzeitig auf den Delegaten zugreifen.
Was kann ich also tun, um diese vielen Definitionen zu vereinfachen oder zu vermeiden?
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 23750
Beitrag hustbaer Mitglied 01:32:44 14.11.2017   Titel:   Re: Zuviele Delegaten....            Zitieren

7x7-7 schrieb:
Verwende ich den selben Delegaten für zwei asynchrone Threads, so kommt es natürlich zu einer Zugriffsverletzung, wenn beide Threads mal gleichzeitig auf den Delegaten zugreifen.

Äh. Kann sein dass ich dich nicht richtig verstehe, aber wenn doch, dann wüsste ich keinen Grund warum es da zu einer Zugriffsverletzung kommen sollte. Mal ganz davon abgesehen dass man Zugriffsverletzungen in C# echt nur sehr schwer hinbekommt so lange man kein unsafe, PInvoke o.ä. verwendet -- aber ich kann mir auch kein anderes Problem vorstellen.

Oder geht es dir darum dass die verschiedenen Threads nicht alle in die selbe RichtextBox rein schreiben sollen, sondern in unterschiedliche?

Kannst du vielleicht zeigen wie der "geht so nicht, weil" Code den du dir vorstellst aussehen würde, und was deiner Meinung nach das "weil" dabei ist?

_________________
Until every person can enjoy all their human rights, we will not stop. I support Amnesty International. Will you?
https://www.amnesty.org / https://www.amnesty.de / https://www.amnesty.at
7x7-7
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.08.2009
Beiträge: 108
Beitrag 7x7-7 Mitglied 09:17:11 14.11.2017   Titel:              Zitieren

Hallo,
und danke für den Beitrag. Ich habe gerade mal eine Testapp gebaut – und ja – in C# scheint es tatsächlich damit erstmal kein Problem zu geben. Was ich hätte vielleicht noch sagen sollen ist, dass alle Threads in Klassenbibliotheken untergebracht sind, die dann auf diesem Weg: https://www.c-plusplus.net/forum/340703 mit der C# APP kommunizieren, die dann als GUI fungiert.
Irgendwann hing sich das Ganze immer mal wieder auf, so dass ich ab fortan jedem Thread seinen eigenen Delegaten zum Bedienen der GUI Grafikelemente zugeordnet habe und alles sodann absturzfrei funktionierte.
Ich habe leider nur noch dunkel in Erinnerung, dass es sich bei der Ursache des Absturzes um eine Zugriffsverletzung auf den Delegaten handelte.
Ausgehend davon sammeln sich mittlerweile um die 50 Delegaten zum Bedienen von z.B. einer richtextBox an, was ich wie anfangs gesagt vereinfachen wollte.
Dravere
Admin

Benutzerprofil
Anmeldungsdatum: 13.06.2005
Beiträge: 8706
Beitrag Dravere Admin 10:02:24 14.11.2017   Titel:              Zitieren

Es bleibt dabei was hustbaer gesagt hat.

Das einzige was mir noch auffällt vom vorherigen Thread: Wieso verwendest du Marshal.GetFunctionPointerForDelegate? Du kannst einen Delegate in C++/CLI definieren und den in deinem C# Programm verwenden und deiner Bibliothek direkt übergeben. Da musst du keinen Umweg über einen Funktionszeiger gehen.

Oder du könntest ein gemeinsames Interface definieren, welches vom C# Programm angeboten wird und von deinen Klassenbibliotheken verwendet wird. Allenfalls in einer weiteren Bibliothek, welche von deinem C# Programm und deinen bisherigen Bibliotheken verwendet wird.

_________________
Danke für die Hilfe, Antwort oder Meinung!
C++: Std-Lib Referenz
C# .Net: MSDN kennt die Antwort
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 23750
Beitrag hustbaer Mitglied 14:40:30 14.11.2017   Titel:              Zitieren

Bei GetFunctionPointerForDelegate ist eines ganz wichtig, was auch in der Doku steh (leider nicht fett rot und blinkend, denn da wäre es angebracht):
Zitat:
You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track references to unmanaged code.

Wenn du dich daran nicht hältst, dann kannst du wirklich Crashes (Access-Violations) bekommen.
Der GC kann nämlich nicht wissen ob dein native Code den Funktionszeiger noch braucht. Trotzdem muss er Delegates (plus deren Native-Call-Thunks auf die die Funktionszeiger zeigen) irgendwie collecten können -- sonst würden die ja auf ewig leaken.

Daher die Regel: Du musst im managed Teil eine Referenz auf den Delegate behalten, so lange der Funktionszeiger im native Teil verwendet werden kann.

Folgendes ist also z.B. FALSCH:
C#:
public void MyMethod()
{
    MyDelegateType dlg = new MyDelegateType(this.MySomethingHandler);
    MyPInvokeStuff.SetFunctionPtr(Marshal.GetFunctionPointerForDelegate(dlg));
}

Wenn die native Komponente danach den Funktionszeiger verwendet, kann es krachen.
Damit es funktioniert, musst du sicherstellen dass das Objekt auf das dlg nicht collected werden kann. z.B. indem du ne Membervariable machst die darauf verweist o.ä.


Wobei sich daran nichts ändert nur weil man MySomethingHandler zwei oder dreifach implementiert.

_________________
Until every person can enjoy all their human rights, we will not stop. I support Amnesty International. Will you?
https://www.amnesty.org / https://www.amnesty.de / https://www.amnesty.at
C++ Forum :: C# und .NET ::  Zuviele Delegaten....   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.