C# Cancel im Eventhandler Programmieren

roker002

Commander
Registriert
Dez. 2007
Beiträge
2.107
Ich habe eine Frage. Einige Events von MS haben eine zusätzliche Variable die mir erlaubt die aktuelle Operation ungültig zu machen. Es ist meistens dort, wo man die Datenmengen behandelt. Z.B. BindingList hat sowas ähnliches. Man kann im ausgelösten Event die neuen Daten verwerfen.

Wie wird es normalerweise realisiert? Ich habe schon eine Vorstellung wie man es Lösen könnte, aber es wäre ja gut zu wissen dass man auch einen optimalen Weg hierzu benutzen kann.

Mein Ansatz.
alles läuft über den Selben Thread.

EventArgs beinhaltet einen zusätzlichen Feld mit "Boolean Cancel". Beim Event Springe ich ja auf dem Methodenzeiger in die Richtige Methode. Dort ist mein EventArg mitübergeben. Sobald ich aus dem Delegate raus bin, bin ich sicher, wieder in meine OnXXXEvent Methode. Wenn jetzt im EventArg Cancel auf "true" gesetzt wurde, nehme ich den neuen Wert und überschreibe dem alten Wert... somit habe ich wieder den alten Wert in meine Klasse zurück bekommen.

Ist diese Vorgehensweise korrekt?

THX
 
Wenn du eine OnXXXEvent Methode Deklariert hast, dann landest du dort wieder und kannst den Parameter überprüfen. Die Vorgehensweiße ist ok.
 
gut... dann ist auch klar wie das ganze abläuft. Ich dachte es wird irgendwie anders geregelt. DANKE
 
Ich hab mir das nochmal durch den Kopf gehen lassen ob du wirklich sowas hier meinst.
Code:
 public class Test
    {
        public delegate void OnShootingEvent(object sender, CancelEventArgs e);
        public event OnShootingEvent Shooting;

        protected void OnShooting()
        {
            CancelEventArgs args = new CancelEventArgs(false);
            if (this.Shooting != null)
                this.Shooting(this,args);

            if (args.Cancel)
            {
                Console.WriteLine("The Operation has been Canceled");
                return;
            }
            Console.WriteLine("The Operation succeded");
            return;

        }
        public void ShootEvent()
        {
            this.OnShooting();
        }
    }

    public class Program
    {
        static void Main()
        {
            Test t = new Test();
            t.Shooting += new Test.OnShootingEvent(t_Shooting);
            t.ShootEvent();

            Console.ReadKey();
            
        }

        static void t_Shooting(object sender, CancelEventArgs e)
        {
            // no more handling
            //e.Cancel = true;
        }
    }
Wenn du e.Cancel einkommentierst dann zeigt er an das die Operation abgebrochen wurde.
 
ja genau das.... bei mir ist halt alles komplexer :D
Danke für den Code.
 
Ich baue eine Klasse die Komplett auf einen bestimmte Tabelle abgestimmt ist. Naja es ist in erste Linie ein Prototyp. Ich möchte sehen ob es auf weitere Tabelle ausweitbar ist. Zumindest habe ich alles so aufgebaut. Einen Interface und Abstract das von Interface Erbt und alle Standardfunktionen vor-implementiert hat. Die Eigentliche Klasse selbst erbt von der Abstract Klasse und hat noch zusätzliche eigene Attribute, die die Konsistenz der Datenbank mit den Datenfeldern (in diesen Fall Properties) überprüft. So kann ich sicher gehen, dass es nur diese eine Version der Datenbank nutzbar ist und nur diese eine Version der DLL.

Zumindest läuft alles wie geplant. Wenn ein Update fehlschlagen soll, will ich die Felder wieder zurücksetzen.
 
Meine anfragen sind sporadisch und daher braucht man keine ständige Verbindung zu dem Server.
 
Na das ist ja kein Problem. Mit den SqlConnection-und-Konsorten Klassen kannst du die Verbindung doch dann aufmachen wenn du es brauchst, machst du vermutlich eh schon nur gekapselt in deiner neuen Klasse. und wenn du eh nur sporadischen zugriff brauchst finde ich den overhead den du erzeugst mit einer extra Klasse für ne Tabelle schon extrem, weil dann bildest du nämlich das ab was ein O/R-Mapper macht und dann rennst du an deiner Aussage vorbei.
 
Ich habe leider gemerkt das der Mapper schlecht mit den Bezeichnern umgehen kann wenn diese in mehreren Tabellen die gleichen sind. Hierbei handelt es sich meist um den Fremdschlüsseln. ich kann ja schlecht alle Bezeichner austauschen ohne das mir das ganze um die Ohren fliegt. Im Bild kann man den Aufbau der DB sehen.

EDIT... ich nehme zurück was ich gesagt habe. Offenbar kann der Mapper nicht gut mit mehreren Instanzen einer Tabelle umgehen. Ich hatte ausprobiert Eine Tabelle als Context zu benutzen, dann die gesamte Datenbank zu Mappen. Da die Tabelle irgendwie bei den Beiden Mappern die gleiche ist, hat der Compiler damit probleme gehabt.


EDIT 2
Ist eigentlich Linq To Sql genau so schnell wie Trans SQL. Irgendwie konnte ich nichts finden was für die Performance spricht.
 

Anhänge

  • Unbenannt.jpg
    Unbenannt.jpg
    40,6 KB · Aufrufe: 266
Zuletzt bearbeitet:
Also zu der Performance kann ich leider nicht sagen, aber mich würden mal deine Quellen interessieren.
Natürlich kann der Compiler nicht mit Tabellen umgehen die mehrfach vorkommen, das ist ja das selbe als wenn du zwei gleichnamige Variablen anlegst. Ich frag mich gerade sowieso warum du zweimal die selben Tabellen hast. Warum den DataContext nicht über ein Mapping erstellen? Und bei solchen Tabellen Ausmaßen könntest du vielleicht doch eher das ADO.NET Entity Framework nehmen.
 
ADO soll angeblich sehr viele Performanceverluste haben.

Das mit der Fehlermeldung wegen 2 Klassen aus Linq-To-Sql, ich habe einfach ausprobieren wollen wie es funktioniert. Dann habe ich eine Tabelle in die ORM hinzugefügt. Dann habe ich die gesamte Datenbank in die andere Linq-To-Sql Datei hinzugefügt, was ebenfalls diese Tabelle enthielt. Ich denke es gab einfach 2 Klasse mit der Selbe Bezeichnung unter den selben Pfad.

Was ADO.NET angeht... es sieht verdammt nach Trans-SQL aus, oder habe ich da jetzt falsche Tutorials angeschaut?
 
Ich finde den Linq To Sql viel einfacher zu verstehen.

Hmm, beide Modelle sind gut. Zumindest sieht man bei ADO alle fremdschlüssel und deren direkt, was bei Linq nur teilweise angezeigt wird.

Ich denke ich werde zuerst auf meinen alten Modell bleiben. ADO kann man sehr gut verwenden wenn man die Daten aus den externen Trägern (wie z.B. Dateien die vorformatiert sind). Beim ADO.NET finde ich aber schade, dass man die Verbindung nicht wirklich selbst setzen kann. Natürlich kann man den Assemblywert überschreiben. Für den Entwickler ist das ja vom Vorteil wenn man den Connection String nicht verwalten muss, aber sobald man die Software weitergeben will, ab da muss man beachten, dass es nicht mehr über den selben Server mehr läuft.

Bei Linq kann man die SqlConnect immer mitgeben und über diese zu arbeiten. Bei ADO fand ich diese Methode nicht mehr!
 
Zurück
Oben