Archiv

Archiv für September, 2009

ClickOnce – Die .NET Antwort auf Java WebStart

13. September 2009 admin Keine Kommentare

Java hat es vorgemacht: Ein einfaches Konzept namens Webstart ermöglicht eine einfache Verteilung einer Anwendung über das Web. Dabei wird die Applikation über einen Browser aufgerufen, welcher die benötigten Downloads automatisch tätigt und die Applikation startet. Diese Art der Softwareverteilung hat gewisse Vorteile wie beispielsweise die Zugreifbarkeit oder die Updatemöglichkeit ohne, dass der Benutzer aktiv werden muss.

Die Antwort von .NET heisst ClickOnce. Das Prinzip dahinter ist grundsätzlich genau gleich. So können Applikationen direkt auf einem Webserver veröffentlicht werden. Die Veröffentlichung von ClickOnce-Applikationen ist dabei spielend einfach. Im Eigenschaften Fenster des Projekts müssten im Reiter “Publish” einfach der Exportpfad sowie der entgültige Pfad auf dem Webserver eingegeben werden. Der Entwickler hat dier noch mehrere Einstellmöglichkeiten welche sich hinter dem “Options” Button verbergen. Wurde der gesamte Export auf den Webserver geladen, kann die Applikation auf 2 Arten gestartet werden:

  • Mit einem direkten Start über die “.application” Datei (funktioniert mit dem IE Einwandfrei, während Firefox dazu evtl. das Addon Microsoft .NET Framework Assistant benötigt)
  • Mit einem vorherigen Download eines Setups, welches prüft ob die vorausgesetzten Software Packages installiert sind (Framework, Windows Installer, etc.).

Als kleines Beispiel habe ich eine Hello World-Applikation gemacht, welche ganz einfach über einen Browser aufrufbar ist.

Starte die ClickOnce-Demo (leitet dich auf eine Seite weiter, welche von Visual Studio generiert wurde und beide obengenannten Startmöglichkeiten verlinkt hat)

KategorienAllgemein Tags:

Threadsichere Aktualisierung von GUIs

5. September 2009 admin Keine Kommentare

Standardmässig lässt C# es nicht zu, dass das GUI von einem anderen Thread aktualisiert wird, als von jenem der es erstellt hat. C# wirf eine InvalidOperationException mit dem hinweis, dass versucht wurde das GUI von einem Thread zu aktualisieren, welche nicht der Besitzer ist. Es gibt jedoch möglichkeiten wie man trotzdem von anderen Threads auf das GUI schreiben kann. Dazu dient beispielsweise die Eigenschaft

Control.CheckForIllegalCrossThreadCalls

Diese ist in C# von Beginn weg auf True gestellt. Es gibt nun zwei verschiedene Möglichkeiten wie man von anderen Threads trotzdem die GUI Komponenten aufrufen kann:

  • Man stellt die obengenannte Eigenschaft auf  false, womit keine Prüfung mehr erfolgt ob es ein threadübergreifender Vorgang ist
  • Man benutzt die InvokeRequired-Methode welche prüft ob ein threadübergreifender Vorgang vorliegt und Methode nochmals vom GUI-Thread aufgerufen werden soll.

Da die erste Möglichkeit mit einer Codezeile erledigt wird, möchten wir uns die zweite Methode genauer anschauen. Dabei kommen Delegates zum Einsatz. Wie der Name schon sagt werden dabei Methodenaufrufe delegiert.  Der Methodenaufruf wird dabei an den den GUI-Thread übergeben, welche die Methode von sich aus aufruft. Damit haben wir das Problem des threadübergreifenden Zugriffs elegant gelöst!

Als kleines Beispiel habe ich ein Projekt erstellt welche einerseits mit der BeginInvoke-Methode arbeitet und andererseits keine Prüfung beinhaltet (also eine Exception wirft). Um die Abläufe der Aufrufe am besten zu verfolgen wird empfohlen das Projekt im Debugging-Modus auszuführen. So ist klar ersichtlich welche Aufrufe wann passieren und es ist leichter nachvollziehbar. Der zentrale Code mit den Delegates lautet folgendermassen:

delegate void ChangeLabelSizeCallback(float newSize);
private void ChangeLabelSize(float newSize)
{
    if (lblTarget.InvokeRequired)
    {
        ChangeLabelSizeCallback lsc = new ChangeLabelSizeCallback(ChangeLabelSize);
        lblTarget.Invoke(lsc, new Object[] { newSize });
    }
    else
    {
        lblTarget.Font = new Font(lblTarget.Font.FontFamily, newSize);
        lblTarget.Text = "FontSize: " + newSize.ToString();
    }
}

Anbei steht das gesamte Beispiel noch zum Download bereit:

Download

KategorienAllgemein, Forms Tags: