2009-03-31 5 views
8
public sealed class FtpManager 
{ 
    public event EventHandler LoggingIn = delegate { }; 
    private void OnLoggingIn(object sender, EventArgs e) 
    { 
     var handler = LoggingIn; 
     handler(sender, e); 
    } 
// ... 
} 

Im obigen Code habe ich LoggingIn Event-Handler mit einem leeren Delegaten initialisiert.

Wird sich der Speicherplatz in irgendeiner Weise auswirken? Vor allem wenn es Hunderte oder Tausende solcher Ereignisse gibt?Wird ein leerer Delegierter Speicher auffressen?

+0

Vergessen Sie nicht den zusätzlichen Methodenaufruf. Sie rufen sowohl die Ereignishandler als auch eine leere Methode auf, die Sie über den anonymen Delegaten zuweisen. Ich habe keine Tests ausgeführt, aber Sie sollten zumindest davon bewusst sein ... –

Antwort

13

Scratch die vorherige Antwort (unten für die Nachwelt gehalten). Es hängt von der Implementierung des Compilers ab, aber unter dem aktuellen MS C# 3.0-Compiler erstellt das tatsächlich nur eine einzelne Instanz, die für jede Instanz wiederverwendet wird. Dies ist möglich, weil Delegaten unveränderlich sind und dieser Delegat keine Informationen von der Instanz benötigt.

Ich weiß nicht, ob dies mit C# 2.0 obwohl der Fall war. Sie können Ihren Code dekompilieren und sehen, ob die IL tatsächlich ein zwischengespeichertes Feld verwendet oder nicht. Die Verwendung der folgenden Antwort ist ein sicherer Weg zu Garantie Sie werden nur eine Instanz erstellen.

Ursprüngliche Antwort:

Ja, erstellt es eine Instanz eines Delegaten. Das wird etwas Speicher brauchen. Sie könnten das aber reduzieren:

public static class EventHandlers 
{ 
    public static readonly EventHandler Empty = delegate {}; 
} 

public sealed class FtpManager 
{ 
    public event EventHandler LoggingIn = EventHandlers.Empty; 
} 

An diesem Punkt wird es nur die eine Instanz sein, und Sie können von überall darauf verweisen. Der Nachteil ist, dass andere Klassen sich dann mit demselben Handler abmelden konnten. Wenn Sie dem Rest Ihrer Codebasis vertrauen, dies nicht zu tun, ist dies aus Sicht des Speichers wahrscheinlich die beste Wahl.

+0

Wow, ich denke, ein Teil der Grund, warum meine App mit hoher Speicherauslastung läuft, könnte sein, weil ich Ereignisse mit einem leeren deklariert habe delegieren...; Danke nochmal, Jon – Sung

+0

@Sung: Ich habe meine Antwort komplett geändert. Will zurückgehen und bearbeiten, um die vorherige Version auch zu setzen! –

+0

@Sung: Okay, es ist jetzt wesentlich vollständiger. Sie sollten in der Lage sein zu überprüfen, ob dies Ihr Problem ist, indem Sie Ihre App dekompilieren. Reflector ist dafür gut, aber Sie müssen sich die IL ansehen, um sicher zu sein, was wirklich passiert. –

-1

Die Alternative dazu besteht darin, LoggingIn jedes Mal auf Nichtigkeit zu überprüfen, wenn Sie es erhöhen möchten. Das ist wahrscheinlich speicherintensiver als das Aufrufen eines leeren Delegierten.

+0

Haben Sie Tests ausgeführt, um dies zu unterstützen, oder ist das nur eine Annahme? –

+0

Nein. Ich habe gerade auf einen begrenzenden Faktor hingewiesen. Wenn Sie Tests wollten, hätten Sie sie genauso einfach schreiben können wie jeder andere auch. –