Forum: PC-Programmierung EventHandler C#


von CsharpUser (Gast)


Lesenswert?

Guten Morgen,

ich benötige einen EventHandler. Dazu habe ich zunächst einen 
EventHandler definiert:
1
public event EventHandler<bool> Connected;

In dieser Funktion wird der bool Wert vom EventHandler auf true gesetzt.
1
public void Test()
2
{
3
            var p = this.Connected;
4
            if (p != null)
5
            {
6
                p(this, true);
7
            }
8
}

Folgende Fehlermeldung erscheint beim übersetzen:
Der Typ "bool" kann nicht als Typparameter "TEventArgs" im generischen 
Typ oder in der generischen Methode "System.EventHandler<TEventArgs>" 
verwendet werden. Es ist keine Boxing-Konvertierung von "bool" in 
"System.EventArgs" vorhanden.

Was mache ich hier möglicheriweise falsch?

von Borislav B. (boris_b)


Lesenswert?

Versuchs doch mal mit
1
public event Action<object, bool> Connected;

Das Auslösen des Events kannst du auch noch etwas kompakter formulieren:
1
if(Connected != null) Connected(this, true);

: Bearbeitet durch User
von Andreas R. (andreasr)


Lesenswert?

> Das Auslösen des Events kannst du auch noch etwas kompakter formulieren:
>
1
> if(Connected != null) Connected(this, true);
2
>

Bitte nicht machen, das ist nicht thread safe!

von Borislav B. (boris_b)


Lesenswert?

Andreas R. schrieb:
> Bitte nicht machen, das ist nicht thread safe!

So hat  CsharpUser  das ja bisher auch gemacht, also bin ich davon 
ausgegangen, dass es das ist, was er will. Ist ja nicht unbedingt 
schlimm.

Alternativ könnte man auch ein Invoke(...) verwenden.

von Andreas R. (andreasr)


Lesenswert?

>So hat  CsharpUser  das ja bisher auch gemacht

Nein hat er nicht, er hat den Event-Handler vor der null-Abfrage einer 
lokalen Variable zugewiesen. Das macht hier den Unterschied aus.

Der eigentliche Fehler liegt darin, dass bool nicht als 
Template-Argument genommen werden kann.
Es muss entweder EventArgs oder eine ableleitete Klasse von EventArgs 
sein.
Wenn man einen boolean versenden möchte muss man den also in eine Klasse 
einpacken. z.B. so
1
class MyEventArgs : EventArgs
2
{
3
    public bool Data { get; set;}
4
}
5
6
public event EventHandler<MyEventArgs> Connected;

: Bearbeitet durch User
von R. (Gast)


Lesenswert?

Andreas R. schrieb:
> Nein hat er nicht, er hat den Event-Handler vor der null-Abfrage einer
> lokalen Variable zugewiesen. Das macht hier den Unterschied aus.

Das erscheint mir auch nicht ganz sauber. Wenn in einem zweiten Thread 
zeitlich zwischen der p-Zuweisung und p-Invoke ein Handler an das Event 
an- oder davon abgehängt wird, wird der Handler nicht oder noch 
ausgeführt. Das ist auch nicht thread safe, wenn auch keine 
NullReferenceException ausgelöst werden kann.
IMHO muss das eh synchronisiert werden, weshalb ich die Lösung von Boris 
P. so auch verwende. Sorry für OT!

Da wir in unserer etwas grösseren Solution öfter mal solche EventArgs 
mit unterschiedlichen Typen brauchen, haben wir eine generische Klasse 
erstellt:
1
public class EventArgs<T> : EventArgs
2
{
3
    private T item;
4
5
    public EventArgs(T item)
6
    {
7
        this.item = item;
8
    }
9
10
    public T Item
11
    {
12
        get { return item; }
13
    }
14
}

von Frank (Gast)


Lesenswert?

Auch wenn das Hauptproblem des TO gelöst sein dürfte, hier ein paar 
Links zum Thema Events und Threadsicherheit:

U.a. Eric Lipperts Sichtweise zum "Stale Handler Problem":

http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

Reihe zu Events in C# 4 und höher:

http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

http://blogs.msdn.com/b/cburrows/archive/2010/03/08/events-get-a-little-overhaul-in-c-4-part-ii-semantic-changes-and.aspx

http://blogs.msdn.com/b/cburrows/archive/2010/03/18/events-get-a-little-overhaul-in-c-4-part-iii-breaking-changes.aspx

http://blogs.msdn.com/b/cburrows/archive/2010/03/30/events-get-a-little-overhaul-in-c-4-afterward-effective-events.aspx

C# 6 "Elvis operator" bei Events sowie Volatile.Read in .NET 4.5 und 
höher:

h*tp://codeblog.jonskeet.uk/2015/01/30/clean-event-handlers-invocation-w 
ith-c-6/

(t = * wegen Spamschutz)

Nicht vergessen, auch die Kommentare zumindest zu überfliegen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.