Biggle's Blog

Web- und Software Development

by Mario Binder

Tuple Eigenschaften lesbar gestalten?

Die Verwendung von Tuple ist eine schnelle Lösung, wenn man beispielweise mehr als ein Parameter oder Rückgabewert benötigt. Ein Anwendungsfall wäre für mich, eine (semantische) Fehlermeldung anstelle von Exceptions. Also ein boolean und ein string als Rückgabewert “Tuple<bool, string>()”. Im string steht dann halt ein Grund drin, warum das Ganze schief gelaufen ist. So weit, so gut.

Das Resultat dabei ist leider nicht lesbar, denn ich bekomme den boolean im Property Item1 und den string in Item2 geliefert.

image

Aber okay, das mag so lange gut gehen, wenn man denn so etwas wie Konventionen für dieses “Pattern”definiert. Das Problem dabei ist hier, dass man sich hier schnell in tiefe Gewässer bewegt. Denn das kann auch ausarten, wenn man denn so etwas hier versucht: “Tuple<bool, string, Exception, bool, bool, decimal>()

image

Hier verliert man ganz schnell den Überblick.

Da hilft auch keine Dokumentation.

Hier käme mir die”glorreiche” Idee, die Tuple Properties lesbarer zu gestalten. Also baue ich mir eine Klasse, die von Tuple ableitet, in etwa so:

image

Nun stehen einem auch die Eigenschaften zur Verfügung.

image

Aber warum sollte ich dann von Tuple ableiten?

Macht kein Sinn. Bringt mir keinen Mehrwert. Ich kann das Ganze auch ohne.

image

Also warum dann Tuples einsetzen?

Was sagst du dazu? Wann setzt ihr Tuples ein? Wann machen Tuples Sinn? Mir fällt einfach kein Anwendungsfall ein.

Halt, vielleicht aber doch, möglicherweise für so etwas hier?

image

Nee, oder ;)

Nichts desto trotz, wer Tuples einsetzt, hat sicher auch seine Gründe dafür. Die mich natürlich brennend interessieren! Also nicht scheuen, 3-5 Minuten Zeit in die Hand nehmen und rein damit als Kommentar.

In diesem Sinne, viel Spaß beim entwickeln : )

by Mario Binder

Erste Schritte mit SignalR

SignalR ist eine von Microsoft entwickelte Client- und Server-Bibliothek. Besser beschreibt das Dino Esposito:

SignalR ist eine integrierte Client- und Server-Bibliothek, die browserbasierten Clients und ASP.NET-basierten Serverkomponenten die bidirektionale und mehrstufige Kommunikation ermöglicht.

Anders ausgedrückt ist die Kommunikation nicht auf einen einzelnen, statusfreien Datenaustausch des Typs Anforderung/Antwort beschränkt, sondern sie dauert an, bis sie ausdrücklich beendet wird. Die Kommunikation findet über eine dauerhafte Verbindung statt, wobei der Client mehrere Nachrichten an den Server senden kann, auf die der Server antwortet. Und vor allem kann der Server asynchrone Nachrichten an den Client senden.”

Ein einfacher Chat

image

Im folgenden, zeige ich wie immer kurz und knackig, ein absolut einfaches Beispiel für die Verwendung bzw. den Einsatz von SignalR.

1.) Mittels NuGet installieren wir SignalR:

Install-Package SignalR

Folgende Komponenten werden dabei installiert und referenziert:

  • Newtonsoft.Json 4.5.7.
  • SignalR.Server 0.5.2.
  • SignalR.Hosting.Common 0.5.2.
  • SignalR.Hosting.AspNet 0.5.2.
  • jQuery 1.6.4.
  • SignalR.Js 0.5.2.
  • SignalR 0.5.2.

2.) Anschließend schreiben wir eine Klasse, die von der Klasse SignalR.Hubs.Hub ableitet:

public class SimpleChatHub : Hub
{
    public void Send(string nickname,string message)
    {
        Clients.HandleMessage(string.Format("{0} wrotes on {2}: {1}", nickname, message, DateTime.Now.ToShortTimeString()));
    }
}

3.) Für das Anzeigen von Informationen referenzieren die notwendigen Scripte und erstellen uns ein paar Felder

(Hinweis: Um die Nachricht mittels Entertaste zu senden, verwende ich zur Hilfe das Plugin JQByte OnEnter.)

<script type="text/javascript" src='@Url.Content("~/Scripts/jquery.signalR-0.5.2.js")'></script>
<script type="text/javascript" src='@Url.Content("~/Scripts/jquery.OnEnter.js")'></script>
<script type="text/javascript" src="@Url.Content("/signalr/hubs")"></script>

<h3>Simple SignalR Chat:</h3>
<input type="text" id="nickname" />
<input type="text" id="msg" onenter="SendMessage();" />
<button id="sendBtn">Send</button>
<ul id='messages'></ul>

4.) In einem Script dann, starten wir unseren SimpleChatHub und handlen das Versenden der Nachrichten.

<script type="text/javascript">

    var hub;
    $(document).ready(function () {
        $('#nickname').val('').focus();

        ConnectingChatHub();
        hub.HandleMessage = function (message) {
            $('<li>').text(message).prependTo('#messages');
        };

        $('#sendBtn').click(function (){ SendMessage()});
    });


    function ConnectingChatHub() {
        hub = $.connection.simpleChatHub;
        $.connection.hub.start()
        .done(function () { })
        .fail(function () { alert("Could not Connect!") });
    }

    function SendMessage() {
        var nickname = $('#nickname').val();
        var msg = $('#msg').val();
        if (msg != '') {
            hub.send(nickname, msg);
            $('#msg').val('').focus();
        }
    }


</script>

Das war’s auch schon, viel Spaß beim entwickeln : )

Achja, am 03.09.2012 gibt es einen .NET Online User Group Termin zum Thema SignalR mit Christian Weyer.

by Mario Binder

Cronjob im Windows Service

Wenn man einen Windows Service für die Erledigung von Aufgaben bereitstellen möchte und den Job beispielsweise jede Nacht um 3 Uhr erledigen muss, sollte man einen Cronjob / Scheduler dazu verwenden.

Aufbau Crontab

* * * * * - - - - - | | | | | | | | | +----- day of week (0 - 6) (Sunday=0) | | | +------- month (1 - 12) | | +--------- day of month (1 - 31) | +----------- hour (0 - 23) +------------- min (0 - 59)

Um aus diesem Format ein Datum zu bekommen, verwende ich die Bibliothek NCrontab. Hiermit ist es mir möglich, aus solch einem Crontab ein Datum bzw. eine Liste der nächsten Terminen / Jobs zu erhalten.

Eine Liste von Terminen, bekommt man mit der Methode GetNextOccurrences().

CrontabSchedule s = CrontabSchedule.Parse("*/5 * * * *"); var dates = s.GetNextOccurrences(DateTime.Now, DateTime.Now.AddHours(1));

Und den nächsten Termin mit der Methode GetNextOccurrence()

CrontabSchedule s = CrontabSchedule.Parse("*/5 * * * *"); var next = s.GetNextOccurrence(DateTime.Now);

Mit der System.Threading.Timer Klasse kann ich diesen Cronjob ausführen. Ein einfaches Konsolenbeispiel sähe so aus:

static void Main(string[] args) { CrontabSchedule s = CrontabSchedule.Parse("*/5 * * * *"); var next = s.GetNextOccurrence(DateTime.Now); var callback = new System.Threading.TimerCallback(TimerElapsed); new System.Threading.Timer(callback, null, next - DateTime.Now, next - DateTime.Now); Console.ReadLine(); } private static void TimerElapsed(object state) { //do things }

Hier führe ich im Beispiel den Job alle 5 Minuten aus. Das heißt meine Methode TimerElapsed wird alle 5 Minuten aufgerufen.

Klar, dieses Beispiel könnte man sicher mit einem normalen Timer erledigen, jedoch wenn man komplexe Zeiten einsetzen muss, wird das schon schwieriger. Mit einem Crontab kann ich sagen “Erledige den Job 3 mal im Monat, einmal vormittags und einmal nachmittags.

Ein paar Beispiele, wie man ein Crontab erstellt findet man hier.

Okay, soweit so gut. Nun heißt der Titel des Beitrags aber “Cronjob im Windows Service”. Ich schreibe diesen deshalb, weil ich mich wunderte, dass der funktionierende Konsolencode nicht in meinem Windows Service funktionierte. Bzw. der Job wurde lediglich ein einziges Mal ausgeführt.

Der Grund dafür ist, das der GarbageCollector die Timer Referenz, die ich in der OnStart-Methode erstellt habe, eliminiert hat.

Um dennoch das o.g. Konstrukt zu verwenden, muss man lediglich eine globale Timer Variable halten.

Das ganze sieht dann so aus:

using System; using System.Configuration; using System.Diagnostics; using System.ServiceProcess; using System.Threading; using NCrontab; ... public partial class MyService : ServiceBase { TimerCallback _callback; private Timer _timer; public MyService() { InitializeComponent(); } readonly CrontabSchedule _scheduler = CrontabSchedule.Parse(ConfigurationManager.AppSettings["cronjob"]); DateTime _next; void TimerElapsed(object sender) { try { //do things } catch (Exception ex) { //.. throw; } } protected override void OnStart(string[] args) { _callback = (TimerElapsed); _next = _scheduler.GetNextOccurrence(DateTime.Now); _timer = new System.Threading.Timer(_callback, null, _next - DateTime.Now, _next - DateTime.Now); } protected override void OnStop() { } }

Die Konfiguration dazu:

<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="cronjob" value="*/5 * * * *" /> </appSettings> </configuration>

Viel Spaß beim entwickeln : )

by Mario Binder

Basta 2012 – Power-Workshop-Tag sichern

Die BASTA 2012 findet auch dieses Jahr wieder in der Rheingoldhalle Mainz statt. Zwischen dem 17. und dem 21.09.2012 werden wieder jede Menge Neuerungen rund um die .NET Entwicklung vorgestellt und behandelt. Eine umfangreiche Session-Übersicht findest du hier.

Basta2012_Banner_viewport_extern

Nur noch bis Donnerstag bis zu 649 Euro sparen!

Besuche die größte unabhängige Entwicklerkonferenz für
Microsoft-Technologien im deutschsprachigen Raum vom *17. – 21. September 2012 in Mainz* und treffe internationale .NET-Experten.

Über *120 Sessions, Workshops und Keynotes* sowie zahlreiche Gelegenheiten zum *.NET-Working* erwarten Dich.

+++ *Nur noch bis Donnerstag*, den 28. Juni, *gratis Power-Workshop-Tag*erhalten und bis zu *649 Euro sparen*! +++

Webseite: http://basta.net

by Mario Binder

Fehler beim Update von Nuget in Visual Studio 2010 Professional

Bei einem Update von Nuget in Visual Studio 2010 Professional  kann es zu einem Fehler kommen.

Entweder man deinstalliert Nuget und installiert die neue Version, oder man spielt den KB2581019 Fix ein, der den Bug in Visual Studio 2010 behebt.

image

Viel Spaß beim entwickeln : )

by Mario Binder

Visual Studio 11 (Beta) – Ein Vergleich der Versionen

Eine Übersicht über die einzelnen Features die in den verschiedenen Visual Studio 2011 (Beta) Versionen enthalten sind, zeigt uns die folgende Vergleichstabelle:

Kategorisiert sind die Features wie folgt:

Debugging and Diagnostics

Testing Tools

Integrated Development Environment

Development Platform Support

Architecture and Modeling

Lab Management

Team Foundation Server

Collaboration

Software and Services for Production Use

Software for Development and Testing

Other Benefits

Ich freue mich sowohl auf den Test- und den Feedback-Manager als auch auf die Scrum-Integration in der neuen Version!

http://www.microsoft.com/visualstudio/11/en-us/products/compare