.NET Blog   ·   .NET Casts   ·   .NET GUI Foren   ·   .NET BlogBook   ·   WPF Blogger   ·   visual studio one   ·   ASP.NET professional

  • ACHTUNG - NEUES BLOG

    Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
Download .NET Essentials Installer
Trickkiste

C#: Google Web API schon getestet?

16.02.06 - .NET, Allerlei
Beitrag von Norbert Eder
 Nein? Dann wird's - wie bei mir - nun absolut höchste Zeit.

Als ersten Schritt muss man sich die Google API unter http://www.google.com/apis/ downloaden und sich einen Account erstellen. Nach dem Account bekommt man eine Google ID zugesendet, mit der 1000 Requests pro Tag durchgeführt werden können.

Nun, als nächsten Schritt einfach ein neues Projekt im Visual Studio erstellen. Nun eine Web-Referenz auf http://api.google.com/GoogleSearch.wsdl erstellen und dem Teil am besten den Namen Google geben. Nun ist das wildeste erledigt.

Eine Abfrage sieht dann in weiterer Folge so aus:


Google.GoogleSearchResult r = s.doGoogleSearch(googleID, keywords,
0, 10, false, "", false, "", "", "");
int estResults = r.estimatedTotalResultsCount;

Google.ResultElement[] elements = r.resultElements;


Damit lässt sich dann schon etwas machen. Und beispielsweise könnte eine sehr einfach Abfrage-Anwendung so aussehen:



  3 Kommentare - 1791 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Objekte und relationale Daten in einer Datenbank

13.02.06 - .NET, Datenverwaltung
Beitrag von Norbert Eder
 Auf die Beiträge von Thomas und meiner Wenigkeit hat sich auch Alex zu Wort gemeldet. Sein Ansatz (angelehnt an den Microsoft SQL Server 2005) verfolgt das Ablegen von Objekten und relationalen Daten ein einer einzigen DB.

Auch hierzu ein paar Gedanken von mir:

Prinzipiell gibt es den Ansatz der ORDBMS (Objektrelationale Datenbank Management Systeme). Dabei wird ein relationales System um objektorientierte Fähigkeiten erweitert. Oft wird auch nur ein objektorientierte Zugriffsschicht darüberlegt. In der Tat werden allerdings keine Objekte mit relationalen Daten vermischt.

Wie würde das Speichern von Objekten zusammen mit relationalen Daten in einer Datenbank in der Praxis aussehen?

Prinzipiell stehe ich dem Vermischen von Objekten mit relationalen Daten eher negativ gegenüber. Der Ansatz von XML-Feldern in einer Datenbank (siehe SQL Server 2005) ist durchaus praktisch und in manchen Fällen auch sinnvoll. Dies jedoch zu nutzen, um Objekte abzulegen macht eher weniger Sinn. Aus folgenden Gründen (wenn ich von Serialisierung spreche, beziehe ich mich auf die XML-Serialisierung):

- Aufwand der Serialisierung. Bedingt durch diesen Aufwand können die Daten ohnehin wieder in eine relationale Struktur gequetscht werden. Performancemässig wird es hier (allerdings hab ich das jetzt nicht getestet) nicht sehr viel Unterschied geben.

- Weiters verleitet dieser Ansatz dazu, eine Tabelle mit mehreren XML-Feldern zu erstellen und darin serialisierte Objekte abzulegen. Eventuell noch von unterschiedlichen Typen. Spätestens dieser Punkt würde durchaus Probleme aufwerfen.

- Durch das einfache serialisierte Ablegen würden in der Datenbank Referenzen nicht mehr ersichtlich sein. In einem reinen relationalen oder reinen objektorientierten System bleibt dieser Vorteil erhalten. Referenzen in XML sind zwar möglich, aber selbst bei einem eigenen XML-Serializer nützt das Einfügen dieser Referenzen wenig, wenn sie durch die Datenbank nicht dargestellt werden können.

Abfragen sind natürlich auch in dieser Form noch auf der Datenbank möglich ohne alle Daten zu laden, aber durch die Vermischung von SQL und XPATH etc. würde ich meinen, dass der Performance-Vorteil eher gering ausfällt -> dürfte wohl im Minusbereich angesiedelt sein.

Und zu guter Letzt: Diese Variante würde kein gemeinsames Ablegen von Objekten und relationalen Daten implizieren. Das einzige was Sinn machen würde, wäre das Ablegen von relationalen Informationen (Metdaten etc.) zu Objekten - aber ich denke das übernimmt ohnehin die Indizierung für uns.

Soweit mal meine ersten Gedanken dazu. Weitere werden vermutlich noch folgen, wenn ich allen "neuen" Gedanken nachgegangen bin ;-)

  3 Kommentare - 1436 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


OODBMS- Object Oriented DataBase Management Systems

07.02.06 - .NET, Datenverwaltung
Beitrag von Norbert Eder
 Bezugnehmend auf den Eintrag von Thomas möchte ich hier noch ein paar Worte zu OODBMS verwenden.

Objektorientierte Datenbanken sind schon sehr nett, aber leider auch nicht für alles einsetzbar. Das schöne daran ist, dass die Objekte an sich gespeichert werden, nicht ein relationales Mapping davon. Dies bedeutet, dass das Mappen von relationalen Daten auf das ursprüngliche Objekt nicht mehr notwendig ist.

Allerdings sehe ich hier doch noch einige Probleme, die nicht unausgesprochen bleiben sollten:

1. Fehlende Standards

Einheitliche Standards zu ORDBMS bzw. OODBMS gibt es nicht - auch wenn es diese Systeme nicht erst seit gestern gibt. Dadurch ist es nicht gewährleistet, dass alle Systeme auf gleiche Art und Weise arbeiten. Object-oriented SQL (OSQL) ist ansich recht nett, aber auch hier gibts die gleichen "Fehler" wie beim herkömmlichen SQL -> Jeder implementiert eine eigene Variante.

2. Backup, Restore, Verteilung etc.

Objekte sind wesentlich komplexer als relationale Strukturen. Entsprechend komplexer wird dadurch auch ein Backup, ein Restore, eine Verteilung oder überhaupt nur die Aktualisierung der Daten, das Nachziehen von Referenzen usw. Diese Dinge sind mit hohem Aufwand verbunden, daher ist eine OODBMS in diesen Gebieten sicherlich langsamer als ein herkömmliches RDBMS.

3. Angst?

Das Thema OODBMS ist ansich genau so alt, wie es objektorientierte Sprachen sind. Letztere haben sich in einigen Bereichen (Enterprise etc.) durchgesetzt. Erstere nicht. Warum? Nun, relationale Datenbanken sind einfacher zu handhaben und wurden über lange Zeit erprobt. Viele haben davor Angst, auf eine "neue" Technologie zu setzen (Anm.: die jedoch nicht viel jünger ist). Dadurch fließt auch nicht soviel Entwicklungsarbeit in objekt-orientierte Ansätze bei Datenbank-Management-Systemen.

4. Fehlende Unterstützung?

Viele Lösungen entstehen und verschwinden entsprechend auch wieder, da die Nutzung nicht vorhanden ist. Ich persönlich kenne nur ein OODBMS welches sich lange gehalten hat. Caché. Alle anderen sind entweder "gemeinnützige" Projekte mit mehr oder weniger geringem Support.

Natürlich gibt es da noch andere Punkte. Der Vollständigkeit halber stehen dem jedoch auch sehr viele Vorteile gegebenüber - keine Frage. Allerdings sehe ich hier db4o nicht unbedingt das als Gelbe vom Ei an. Aber der Weg den db4o beschreitet ist prinzipiell nicht so schlecht.

Just my 2 cents.
  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Microsoft Expression - Windows Presentation Foundation

05.02.06 - .NET, WPF
Beitrag von Norbert Eder
 Eine Technologie mit vielen Namen und vor allem auch Gesichtern. WinFX. Bis jetzt hatte ich noch keine Zeit mir diese Technologie inkl. der bereits vorhandenen Produkte (im CTP-Status) näher anzusehen. Jetzt wirds aber Zeit.

In den nächsten Tagen werde ich mich ein wenig damit herumspielen und auch entsprechendes berichten.

Ich bin schon sehr gespannt.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C#: Methode mit Parameter via ThreadStart aufrufen

29.01.06 - .NET, Base Framework
Beitrag von Norbert Eder
 Im heutigen Beitrag zum Thema "C# Beginner" möchte ich ein Beispiel zeigen, wie mittels ThreadStart eine Methode inkl. Parameter aufgerufen werden kann.

Dazu ist einfach die entsprechende Methode in eine eigene Klasse mit den notwendigen Properties auszulagern:

private class TestClass {

private string parameter = null;

public string Parameter {
get { return this.parameter; }
set { this.parameter = value; }
}

public void Start() {
// code goes here
}

}

In der ursprünglichen Klasse wird der Thread wie folgt gestartet:

TestClass tc = new TestClass();
tc.Parameter = "test";
Thread t = new Thread(new ThreadStart(tc.Start)).Start();

Das wars dann auch schon wieder.

  1 Kommentar - 2826 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Einführung Garbage Collector

11.01.06 - .NET, Grundlagen
Beitrag von Norbert Eder
 Garbage Collection unter C# sieht im Prinzip folgendermaßen aus:

Der GC wird meist dann angetriggert, wenn der Heap-Speicher aufgebraucht sprich voll ist, manuell gestartet wird, oder wenn ein anderes Programm mehr Speicher benötigt, als aktuell noch frei ist.

Der GC iteriert durch den Heap und markiert zuerst jedes Objekt als Garbage, also setzt es auf "zu verwerfen". Danach wird nochmals jedes Objekt rekursiv überprüft, ob Referenzen darauf zeigen - es also noch benutzt wird. Jedes Mal, wenn ein Objekt vom Garbage Collector besucht wird, wird es als erreichbar markiert. Nach diesem Durchlauf steht nun fest, welche Objekte erreichbar sind und welche nicht. Zyklische Referenzen (also Objekt A referenziert Objekt B, welches Objekt C referenziert, welches wiederum Objekt A referenziert) werden ebenfalls entsprechend behandelt.

Im nächsten Schritt wird der Managed Heap durchlaufen und dieser kompaktiert. Das bedeutet, dass Objekte, die verworfen werden können durch Objekte, die im Heap weiter oben gelagert sind überschrieben werden. Dadurch verkleinert sich der Heap und benötigte Objekte wandern weiter nach unten. Es entstehen also keine "Löcher" Heap (Fragmentierung). Dadurch müssen natürlich auch alle Referenzen vom GC geändert werden. Dies ist natürlich ein aufwändiges Unterfangen und aus diesem Grund sollte der GC manuell nur aufgerufen werden, wenn dies unbedingt notwendig ist.

Wann werden Objekte nicht mehr benötigt? Beispielsweise werden in einer Methode unterschiedliche Objekte instanziert. Wurde diese Methode durchlaufen, werden diese Objekte natürlich nicht mehr benötigt und werden beim nächsten Durchlauf des GC entsprechend behandelt. Sie müssen also nicht explizit auf null gestellt werden. Anders verhält es sich bei Objekten, die "expensive resources" (Dateien, Socket-Verbindungen, Ports, Daten Strukturen etc.) enthalten. Hier bietet .NET die object finalization an. Werden also Verbindungen etc. benutzt sollte eine Methode Finalize() vorhanden sein. Diese wird bei der Freigabe des Objektes aufgerufen und somit können verwendete Resourcen auch entsprechend behandelt bzw. tatsächlich freigegeben werden. Hier ist zu beachten, dass die Finalize()-Methode der Basisklasse auch aufgerufen wird. Weiters immer einen try-catch-Block darum ziehen.

Eine weitere Möglichkeit besteht durch das Dispose()-Pattern. Hier ist eine Methode Dispose() zu implementieren. Durch den Aufruf von Dispose werden alle teuren Resourcen entsprechend freigegeben - wie auch in der Finalize()-Methode muss hier der Code für die Freigabe der Ressourcen manuell eingetragen werden. Die Ressourcen werden durch diesen Aufruf sofort freigegeben - ausser man wartet auf den Garbage Collector.

Die schönere Variante besteht darin, das IDisposable()-Interface zu implementieren. Dadurch wird die Methode Dispose() vorgeschrieben und muss entsprechend implementiert werden.

Natürlich gäbe es an dieser Stelle noch mehr zu sagen, aber das sollte als kurzer Überblick durchaus reichen.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


Drucken unter C#

30.12.05 - .NET, Base Framework
Beitrag von Norbert Eder
 Obwohl es ansich relativ viele Ressourcen im Internet zum Thema 'Drucken unter C#' gibt, wird immer wieder die Frage danach aufgeworfen.

Daher an dieser Stelle ein Codebeispiel:

PrintDocument printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
PrintDialog pd = new PrintDialog();
pd.Document = printDoc;
if (pd.ShowDialog() == DialogResult.OK)
{
printDoc.Print();
}

Was genau passiert hier? Zum Ersten wird ein Dokument angelegt. Dieses stellt quasi die Fläche dar, die ausgedruckt werden soll. Zudem wird ein EventHandler auf das Event PrintPage gelegt um feststellen zu können, wann genau gedruckt wird.

Durch den PrintDialog kann ein Druck-Dialog zur Auswahl des Druckers angezeigt werden.

Durch Aufruf der Methode Print() des PrintDocuments wird der Druck gestartet, wodurch das Event PrintPage ausgelöst wird. Darin muss nun der zu druckende Inhalt in das erhaltene Graphics-Objekt geschrieben werden:

private void printDoc_PrintPage
(object sender, PrintPageEventArgs e)
{
String textToPrint = "Test-Ausdruck";
Font printFont = new Font("Arial", 18, FontStyle.Bold);
e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, 10, 25);

In diesem Fall wird angegebene Text mit in der Schrift Arial, Schriftgröße 18 und fett auf den Koordinaten x = 10 und y = 25 gedruckt.

Es lohnt sich auch, einen Blick auf die PrintPageEventArgs zu werfen.

  2 Kommentare - 1195 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C# - Daten zwischen zwei Formularen austauschen

23.12.05 - .NET, WPF
Beitrag von Norbert Eder
 Immer wieder wird die Frage gestellt, wie denn Daten zwischen zwei Formularen ausgetauscht werden können.

Hierfür habe ich kurz ein kleines Testprogramm geschrieben, welches genau dies zeigen soll.

Im Projekt sind zwei Forms zu finden und eine Klasse DataExchange. Diese wird von beiden Formularen verwendet und enthält die entsprechenden Daten.

Aber seht euch doch einfach das Projekt an. Bei Fragen kann ich immer ncoh weiterhelfen ;-)

Download Source DataExchange.zip

Das Projekt wurde unter .NET 1.1 erstellt, sollte aber auch unter 2.0 lauffähig sein ;-)
  2 Kommentare - 1571 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C# und Properties

22.12.05 - .NET, Grundlagen, Base Framework
Beitrag von Norbert Eder
 Properties sind öffentliche Eigenschaften von Klassen, die private Member kapseln.

Das klingt jetzt kompliziert, ist es aber nicht:

Prinzipiell ist es so, dass einfache Variablen in Klassen immer privat und daher von ausserhalb der Klasse nicht erreichbar sein sollten. In machen Fällen muss aber auf Werte der Klasse (wenn instanziert, dann Objekt) zugegriffen werden. Dies kann auf mehrere Arten passieren:

1. Die Variablen werden mittels public als öffentlich markiert
2. Es werden Properties eingeführt

Variante 1 sollte nicht angewendet werden, also bleibt im Endeffekt nur Variante zwei. Wie sieht das anhand eines Sourcecode-Beispieles aus?


public class Test {

private string name = null;

public string Name {
get { return this.name; }
set { this.name = value; }
}

}


Wie an diesem Beispiel zu sehen, wird in der Variable name ein Wert gespeichert. Zugegriffen kann auf diesen Wert mittelns der Eigenschaft Name werden. Hierzu ist zu beachten, dass Properties (unterschiedlich zu Methoden) kein () nach dem Methodennamen enthalten, also auch keine Parameter übergeben bekommen können. Weiters gibt es die Bereiche get und set. Im get-Bereich wird der in name gespeicherte Wert zurückgegeben. Der set-Bereich dient dazu, den übergebenen Wert in die private Variable zu speichern. Das Schlüsselwort value beinhaltet hierbei den übergebenen Wert. Dies sieht ausserhalb der Klasse so aus:


Test myTest = new Test();
myTest.Name = "mein Name";
Console.WriteLine(myTest.Name)

Consolen-Ausgabe:
mein Name


Nun gut, aber welchen Vorteil hat das ganze nun? Ganz einfach. Durch eine Property kann beispielsweise eine Überprüfung der Werte durchgeführt werden. Zum Beispiel könnte im set-Bereich die Länge des überprüften Wertes abgefragt werden. Überschreitet dieser eine bestimmte Vorgabe, wird der Wert nicht zugewiesen und der alte Wert bleibt erhalten.

Ein Fehler, der oft gemacht wird, ist folgender:

private string name = null;

public string Name {
get { return this.Name; }
set { this.Name = value; }
}


Was genau passiert hier? Sowohl im get-, als auch im set-Bereich wird immer wieder dieselbe Property aufgerufen, was in weiterer Folge zu einem Stack-Überlauf und daher zu einer StackOverflowException führt. Hier ist wirklich darauf zu achten, auch tatsächlich die private Membervariable anzugeben.

  Kommentar hinzufügen   |  0 Trackbacks   |  Permalink  |  Trackback-URL


C# und Schach ...

30.11.05 - .NET, Allerlei
Beitrag von Norbert Eder
 Wer mit C# arbeitet und in der Freizeit auch die eine oder andere Schach-Partie spielt, der kann sich auf CodeProject eine kleine, nette Schach-Implementierung ansehen.

Eigentlich ganz interessant ...
  Kommentar hinzufügen - 7 mal angesehen   |  0 Trackbacks   |  Permalink  |  Trackback-URL



Zurück