Laden...
Avatar #avatar-2834.jpg
Rainbird myCSharp.de - Experte
Fachinformatiker (AE) Mauer Dabei seit 28.05.2005 3.728 Beiträge
Benutzerbeschreibung
Ich mag Tee lieber als Kaffee.

Forenbeiträge von Rainbird Ingesamt 3.728 Beiträge

25.08.2010 - 07:41 Uhr

Hallo Stipo,

Dir ist aber schon klar, dass die Socket-Verbindung erst hergestellt wird, wenn ein Methodenaufruf über den Proxy stattfindet und dass der Socket anschließend wieder freigegeben wird (ggf. verbleibt der Socket noch einige Zeit in einem Pool/Cache)?

Es nicht so, dass Remoting eine Verbindung zum Server öffnet, wenn der Proxy erzeugt wird und diese über die gesamte Lebensdauer des Proxies aufrechterhält.

Das macht eine IsConnected-Abfrage etwas schwierig. Die Verbindung besteht ja nur für einen ganz kurzen Moment (und das ist auch gut so, da ansonsten Dinge wie Network Load Balancing nicht möglich wären). Auch wenn der Socket nach dem Aufruf noch eine Zeit lang in einem Cache vorgehalten wird, ist er trotzdem nicht mehr mit einem konkreten Objekt verknüpft.

Die Frage ist, ob IsConnected den tatsächlichen Zustand der Socketverbindung zum Server zurückgeben soll/muss? Wenn dem so ist, wäre die Property zu 99.9% der Lebenszeit des Proxies auf False gesetzt.

Die nächste Frage ist, wo Du die IsConnected-Variable einbauen willst?

Generell hast Du bei Remoting keine direkte Kontrolle über die Socketverbindung, da diese von der TransportSenke (transport sink) des verwendeten Remoting-Kanals gekapselt ist.
Wenn Du - warum auch immer - volle Kontrolle über die Socketverbindung haben willst, müsstest Du einen eigenen Remoting-Kanal implementieren (ähnlich wie die vorgefertigten TcpChannel, HttpChannel und IpcChannel). Das ist allerdings ein etwas größerer Aufwand, da der Channel selbst und auch seine Transportsenken implementiert werden müssen. Für gewöhnlich werden eigene Kanäle nur dann geschrieben, wenn man ein Protokoll (z.B. UDP, SMTP oder ein eigenes properitäres Protokoll) zusammen mit Remoting verwenden will, dass standardmäßig unterstützt wird.

Hier ein Beispiel für die Implementierung eines UDP-Kanals: UDP Custom Channel C# .NET Remoting Program Example
Achtung! Der Link enthält mehere Kapitel! Ganz unten auf der Seite kann man weiterblättern (sieht man nicht unbedingt auf den ersten Blick).

Geht es Dir bei der IsConnected-Geschichte um Fehlerbehandlung?

24.08.2010 - 13:28 Uhr

Hallo Stipo,

da gibt es Möglichkeiten.

  1. Über einen TrackingHandler: MSDN: .NET Remoting Überwachungsdienst
  2. Über ein eigene clientseitige Kanalsenke, die den Verbindungsstatus protokolliert und z.B. über Events der Client-Anwendung mitteilt.

Warum ist der Verbindungsstatus so wichtig für Dich?

Remoting kümmert sich automatisch darum.
Wenn Dir das Caching der Sockets auf den Keks geht (zwecks NLB etc.) kannst Du das per Channel-Property abschalten und den Timeout auf 0 setzen. Dann macht Remoting für jeden Aufruf einen eigenen Socket auf.

15.08.2010 - 00:15 Uhr

Hallo bSharp,

soweit mir bekannt ist, gibt es keine Möglichkeit die Umbrüche bei Tabellen sinnvoll zu steuern, außer den von dir bereits erwähnten Einstellungen. Das ist ein großes Manko von RDLC. Bei mehrzeiligem Tabellenlayout (also mehr als eine Zeile pro Datensatz) ist das besonders übel. RDCL noch mehr Probleme. Zum Beispiel kann man den Seitenkopf nicht sinnvoll ausblenden, weil der Platz dafür trotzdem freigelassen wird.

Am Ende ist RDLC aber trotz dieser "Bugs" um Welten besser als Crystal Reports.

Du kannst also entweder damit leben, oder Dir eine eigene Rendering-Erweiterung schreiben, die solche Bugs nicht hat (Aufwändig, aber möglich). Oder Du besorgst Dir eine andere Reporting-Engine. Dafür wirst Du aber harte Euros auf den virtuellen Ladentisch legen müssen.

WPF bringt zwar Print-Unterstützung mit FixedDocument und FlowDocument mit, aber das kann nicht als einsetzbare fertige Reporting-Lösung bezeichnet werden. Das ist momentan eher noch ein loser Werkzeughaufen und paar nicht entkratete Schrauben.

Also ist RDLC immer noch das kleinere Übel. Die Enduser müssen wohl lernen, dass sie gedanklich nicht von Word ausgehen sollten, wenn es um Berichte geht.

10.08.2010 - 09:07 Uhr

Hallo Pria,

das ist gar nicht so schwer wie Du denkst. Du kannst das mit einem benutzerdefinierten Proxy machen. Dazu musst Du eine Proxy-Klasse schreiben, welche von RealProxy (hier ist auch ein Beispiel zu finden) abgeleitet wird.
Du musst dann nur die Invoke-Methode überschreiben.

Der Proxy wird nach der Erzeugung Transparent gemacht. Der Transparente Proxy kann in die gewünschte Schnittstelle gecastet werden.
Idealerweise baust Du Dir noch eine ProxyFactory<T>, die sich um die Proxyerstellung und die Rückgabe des Proxys in der richtigen Schnittstelle kümmert.

Wenn Du dann Methode X von Schnittstelle Y an Proxy Z aufrufst, dann wird eine Message erzeugt, welche Methodenname und Parameter enthält. Diese Message wird an die Invoke-Methode des Proxys übergeben.

So lässt sich eine Art AOP mit .NET Bordmitteln bauen. Bedenke allerdings, dass der eingezogene Proxy auch Auswirkungen auf die Performance hat. Die Proxy-Geschichte kommt .NET Remoting (WCF verwendet aber das selbe Verfahren, um seine Proxies zu erzeugen - deshalb wird uns .NET Remoting auch erhalten bleiben 😄) und ist ist nicht dafür entworfen worden, um Call-Interception für fingranulare komplexe Objektmodelle zu ermöglichen, sondern eher für entfernte Dienstklassen.

Richtig eingesetzt, sind Proxies aber ein mächtiges Werkzeug!

10.08.2010 - 08:45 Uhr

Hallo zusammen,

nein, optinale Parameter müssen bei Reflection nicht angegeben werden, wenn man zusätzlich System.Reflection.BindingFlags.OptionalParameterBinding angibt.

29.07.2010 - 23:55 Uhr

Hallo DonC,

was für eine Art von Anwendung schreibst Du denn?
Warum möchtest Du eine Positionen über einen callback zurück zum Client senden?

Ich frage das, da Callbacks einige Nachteile mit sich bringen. Es gibt Leute, die bi-direktionale Kommunikation verwenden, obwohl sie das für ihre Problemstellung gar nicht bräuchten.

Ich brauche mehr Informationen über Deine Anwendung, damit ich Dir helfen kann.

Wofür ist überhaupt die GeneralSystemMessage? Klingt nach Eierlegenderwollmilchsau.

29.07.2010 - 06:35 Uhr

Option 3 schient mir eigentlich am sinnvollsten, mir ist hierbei nur nicht klar, wie die Anmeldedaten des Benutzers am Master-PC an die anderen Rechner übertragen werden können.

Das ginge z.B. per Remoting-Callback. Bei Starten abonnieren die Clients beim Applikationsserver Benachrichtigungen bei Bedienerwechsel. Christoph Burgdorf hat eine schöne Erweiterung geschrieben, mit welcher sich genau das Abbilden lässt und die auch technisch zu meinem Beispiel passt: NotificationService als Erweiterung zu Rainbirds ApplikationServer Beispiel

So kommen die Anmeldedaten (sprich Benutzername, Domäne und Passwort) vom Master-PC über den Applikationsserver zu den Clients. Die Clients müssen sich nun im Hintergrund als neuer Bediener mit den erhaltenen Anmeldedaten anmelden. Das geht mittels LogonUser (Eine genaue Beschreibung dafür findest Du hier: MSDN: Windows.Sicherheit integrieren). LogonUser gibt einen Zeiger (IntPtr) auf ein Sicherheitstoken (das ist der Nachweis, dass der Benutzer korrekt authentifiziert wurde). Mit Hilfe dieses Sicherheitstokens kann man nun innerhalb der laufenden .NET-Applikation impersonieren (MSDN: WindowsIdentity.Impersonate-Methode). Nun läuft die Client-Anwendung im Kontext des neuen Bediners. Die Impersonierung kann auch jederzeit wieder aufgehoben werden (Undo-Methode).

So könnte eine Lösung mit Windows-Sicherheit aussehen. Negativ daran ist, dass mit Windows-Passwörtern hantiert werden muss, aber das lässt sich nicht anders machen.

Plan B wäre eine ganz eigene Benutzerverwaltung aufzusetzen. Das hat dann aber den Nachteil, dass u.U. in den Prozess eingebundene Fremdprogramme damit nichts anfangen können.

27.07.2010 - 23:40 Uhr

Hallo koller,

sorry, aber ich das Dein Problem nicht wirklich verstanden. Kannst Du das noch etwas näher beschreiben?

27.07.2010 - 21:31 Uhr

Aber was meinst Du wieviele Entwickler, die jetzt von VB6 umsteigen sind so Sattelfest das das Sinn macht?

Bestimmt sind es starke 50% nicht. Genau kann ich das nicht sagen. Kommt auf das jeweilige Team an. Ich habe schon Projekte gesehen, bei welchen die Entwickler so sattelfest waren.

27.07.2010 - 07:22 Uhr

Zu den drei Schichten sei noch angemerkt, dass zwischen Tiers und Layers unterschieden werden muss (Im Deutschen wird beides mit Schichten übersetzt). Der große Unterschied dabei ist, dass Tiers verteilbar (auf verschiedene Prozesse/Maschinen) sind und Layers nicht. Manche Leute sprechen auch von logischen und physischen Schichten, um diesen Unterschied herauszustellen.

27.07.2010 - 07:18 Uhr

Ein sehr gutes kostenloses Tool dafür ist Fiddler. Macht HTTP-Kommunikation im Klartext sichtbar. Inclusive Header etc. PP.

27.07.2010 - 07:16 Uhr

Denn dann bleiben sie bei der Architektur von einem VB6 COM Projekt ...

Das muss nicht sein. Wenn die alten VB6-Module nur über eine eingezogene Integrationsschicht auf die neuen .NET Assemblies zugreifen (und umgekehrt), lässt sich das trennen. Es ist aber - wie gesagt - etwas mehr Arbeit.

und diese Architektur mag sich ja in den letzten 12 Jahren bewährt haben, ist aber bei den neuen Möglichkeiten und Wegen suboptimal und mit .NET mitteln dann auch nur durch viel Frickelarbeit zu lösen ( z.b. Interop Toolkit ).

Wenn sich das "Frickeln" auf die Integrationsschicht beschränkt oder auf VB6-Seite bleibt ist das okay, da die VB6-Module dann ja nach und nach entsorgt werden. Nur in den neuen .NET-Modulen (außer der Integrationsschicht) muss alles sauber bleiben. Dort darf z.B. niemals ein COM-Objekt instanziiert werden. Wenn, dann wird es in einen .NET-Wrapper verpackt und von der Integrationsschicht injeziert.

Ich finde es eher bedenklich langsam zu migrieren, dann schleppt man nämlich den ganzen VB6 Müll mit ...

Natürlich dauert es länger. Dafür benötigt es wesentlich weniger Ressourcen. Niemand muss parallel das alte System pflegen, bis das neue komplett fertig ist (was u.U, Jahre dauern kann, wenn es komplett neu geschrieben werden muss). Die Kunden werden u.U. auch Stück-für-Stück auf die neue Technologie gehoben.
Wenn z.B. ein kleines Team eine große Anwendung über Jahre entwickelt hat, ist die komplette Neuentwicklung u.U. gar nicht zu stemmen.

... und da habe ich persönlich in den letzte 10 Jahren Sachen gesehen.....

Das kann ich mir vorstellen. Ich verstehe auch, dass Du deshalb "vorbelastet" bist, was Migrationsprojekte angeht. Meistens kommen solche Projekte zum Kollaps, wenn die Entwickler in der neuen Technologie nicht wirklich sattelfest sind und/oder alte und neue Welt direkt miteinander zu einem riesigen Klumpatsch verwoben werden.

Aber es muss nicht zwangsweise so sein! Es geht auch anders.

26.07.2010 - 08:22 Uhr

Und ihr solltet das nicht als ein Migrationsprojekt ansehen, dann werdet ihr scheitern.

Diese Aussage halte ich für zu pauschal. Das klingt nach "Schauen wir mal in die Kristallkugel". Natürlich ist es utopitsch zu glauben, man importiert den VB6-Code mit dem Migrations-Assistenten von Visual Studio und fertig ist das neue .NET Projekt. Den Eindruck hatte ich aber von marcelws aber definitiv nicht.

Da es praktisch neu geschrieben wird, tendieren wir dazu dieses System mit WCF/WPF aufzusetzen.

WCF liegt auf der Hand. WPF würde ich mir derzeit noch gut überlegen. Man erreicht bei WPF nicht mal annähernd die Produktivität wie bei Windows.Forms. Der Visual Studio-Designer ist grauenhaft bis unbrauchbar und Expression Blend ist eher was für Künstler, als für Entwickler. Hinzu kommt, dass es besonders für die alten VB6-Hasen ein krasser Schnitt ist. Windows.Forms funktioniert fast genauso wie die Forms in VB6, aber WPF ist komplett anders. Darüber solltest Du nachdenken. Das Neuste muss nicht immer das Beste sein!

Abgesehen davon weiss ich nicht ein mal ob ein Excel Plugin überhaupt in der Lager wäre einen WCF Service zu konsumieren.

ja kann es! Sogar VBA kann das. Du musst nur das SOAP Toolkit bzw. die Redistribution davon auf den Clients installieren: Download Microsoft SOAP Toolkit 3.0

Eventuell hat ja irgendwer schon Erfahrungen damit gemacht. Ich wäre sehr sehr froh wenn jemand von euch mit mir über die Architektur diskutieren würde 😃

Ich habe Erfahrung in der Migration von VB6 und Access auf .NET. Auch in Sachen verteilte Anwendungen und Enterprise Services (COM+). Wenn Du die aktuelle Architektur etwas näher beschreibst, können wir gerne darüber diskutieren.

Ihr wollt das ganze komplett neu schreiben? Es gibt auch die Möglichkeit einer fließenden Migration. Dabei wird die Applikation modulweise, also Stück für Stück migriert. Das erfordert etwas zusätzlichen Aufwand, für Interop-Glue-Code, aber die Anwendung muss dafür nicht zweigleisig supported werden. Für VB6 gibt es sehr gute Unterstützung, um .NET Assemblies in der "Alten Welt" aufzurufen. Da sei allen voran z.B. das Interop Forms Toolkit genannt. Vielleicht ist fließende Migration ja auch ein Thema.

13.07.2010 - 12:45 Uhr

Hallo blr,

mit der Express-Version kannst Du nur einen lokal installierten SQL Server als Datenquelle verwenden. Dabei können die Datenbanken nur dynamisch über die Adressierung der Datenbankdatei angesprochen werden.

Bei Dir handelt es sich um eine sog. Benutzerinstanz (Angabe von "User Instance=True" in der Verbindungszeichenfolge).

Benutzerinstanz heißt, dass die Datenbank für einen einzelnen Benutzer isoliert läuft. Meistens möchte man eine zentrale SQL Server-Datenbank aber gemeinsam im Netzwerk verwenden. Das geht mit Benutzerinstanzen so nicht. Außerdem haben Benutzerinstanzen viele weitere Einschränkungen (Siehe dazu: http://msdn.microsoft.com/de-de/library/ms143684.aspx).

Du solltest prüfen, ob eine dienstbasierte (normale) SQL Server Datenbank für Dein Projekt nicht besser geeignet ist.

Die kannst Du zwar in Visual C# Express nicht als Datenquelle anlegen, da die Express-version das eben nicht unterstützt, aber Du kannst die Verbindung einfach per Code herstellen. Das geht immer. Infos dazu findest Du hier: http://msdn.microsoft.com/de-de/library/bb979090.aspx

26.06.2010 - 16:59 Uhr

Es geht 1. mit einem Request/Response Pin
Gehen tut es, aber das ist nicht der standardmäßig vorgeschlagene Weg. Der sieht eine Aufteilung von Parametern und Rückgabewerten vor in zwei Pins vor.

Natürlich schränkt es ein, wenn man Request/Response mit einem einzigen Pin abbildet, aber oft ist das genau das was man möchte. Wenn man die Antwortnachricht dann doch einmal an eine andere Komponente als die Aufrufer-Komponente senden will, dann kann man ja einen Splitter dazwischen stecken.

Ich sehe nicht ein, warum ich mit den doppelten Aufwand machen soll, wenn das im konkreten Fall keine Vorteile bringt.

Das heißt jetzt nicht, dass ich generell nur mit Func<Q,R> arbeite. Es gibt Fälle, bei denen macht Action<T> definitiv mehr Sinn.

25.06.2010 - 08:43 Uhr

Warum jemand auf die Rückantwort warten soll, hat folgenden Grund:
Wenn ich möchte, dass Komponente A eine bestimmte Arbeit erledigt, bei der ein Ergebnis produziert wird, dann kann ich leider nur Däumchen drehen, bis das Ergebnis da ist. Es sei denn ich habe noch andere Sachen zu tun, die ich in der Zwischenzeit machen kann. Wenn ich aber z.B. ein neu erfasstes Angebot einbuche, dann warte ich - als Mensch - die 60 ms, bis die Rückmeldung da ist, dass alles geklappt hat (oder auch nicht).

Wenn ich dagegen eine Dublettenprüfung meiner 200.000 Kunden-Stammsätze anstoße, dann möchte ich nicht solange blockiert sein, bis das fertig ist (es könnte viele Minuten dauern). Dann lasse ich mit async. per Nachricht informieren, wenn es fertig ist.

Das isnd zwei ganz vierschiedene Paar Schuhe.

Typische Einsatzgebiete für asynchrone Kommunikation sind auch Fortschrittsbalken. Ich möchte z.B. wissen, wie weit mein Upload zum Server ist.

Bei verteilten Komponenten sieht es so aus, dass für jede Client-Anfrage ein eigener Arbeits-Thread erzeugt wird. Sonst könnte der Applikationsserver ja nur einen Client zu selben Zeit bedienen. Mit der Beschaffenheit der Methoden hat das aber wenig zu tun.

25.06.2010 - 08:18 Uhr

Hallo Ralf,

Func<Q,R> hat den Vorteil, dass ich bei Komponenten, die viele Operationen anbieten, nur die Hälfte der Pins in der Schnittstelle habe.

Wenn ich dann doch mal die Antwortnachricht woanders hinschicken muss, dann setze ich einen Splitter dazwischen:


public class RequestResponseSplitter
{
    public Action<T> Out_Response;

    public Func<Q,R> Out_RequestResponseCall;

    public object In_SplitCall(object message)
    {
        object response=Out_RequestResponseCall(message);

        Out_Response(response);
    }
}

Und schon bin ich wieder im Geschäft!

25.06.2010 - 07:51 Uhr

Mit Rückgabewerten skaliert die Anwendung dann leider nicht mehr so gut. Eine Umstellung auf Threads oder sogar Remoting fällt dann deutlich schwerer.

Als jemand, der sich igerade intensiv mit dem Verteilungsaspekt von EBCs befasst, muss ich da widersprechen. Die Anwendung ist nicht mehr oder weniger skalierbar, egal ob Request-Response-Aufrufe (also Methoden mit Rückgabewerten) gemacht werden, oder nicht. Für die Skalierbarkeit ist entscheidend, dass die serverseitigen Komponenten statuslos sind und eine möglichst kurze Lebenszeit haben (oder über Objektpool verwaltet werden). Der großen Serverfarm ist es egal, wie die Methoden aussehen. Da kommt es auf den effektiven Umgang mit den Serverressourcen an und auch darauf, dass die Kommunikation nicht zu "chatty" ist, da dies hohen Netzwerk-Overhead zur Folge hätte.

Was die Verteilung an sich angeht, ist es sogar einfacher, mit Rückgabewerten zu arbeiten, da die gängigen Kommunikations-Frameworks WCF und Remoting beide primär auf RPC fokussiert sind.

Wenn ich Request-Response haben will, dann muss das synchron sein. Der Anfrager, wartet ja auf seine Antwort. Da bringt Multithreading nix. Es sei denn eine Berechnung wird aus Performanc-Gründen in mehrere Threads aufgeteilt. Dann wartet die Anfrager-Komponente eben solange, bis alles verarbeitet ist. Deshalb sehe ich auch da bei Rückgabewerten kein Problem.

Die Verwendung von Func<Q,R> gegenüber Action<T> hat einen ganz anderen Nachteil. Es kann nur die Komponente die Antwortnachricht empfangen, die auch die Anfrage gestellt hat. Das ist eine große Einschränkung.

Wenn ich das aber weiss und mir diese Einschränkung nichts ausmacht, dann ist es okay.

Es kommt immer darauf an, was man erreichen will. Pauschalaussagen sind meistens falsch!

25.06.2010 - 00:14 Uhr

Hallo Zusammen,

hier werden schon ernsthafte Anstrengungen für einen EBC-Designer unternommen: Diagramme für EBCs (Event Based Components) zeichnen / eigenen EBC-Designer realisieren

Den Begriff IBC finde ich sehr schwammig, da er in den meisten EBC-Diskussionen für alles benutzt wird, was nicht EBC ist. Insofern ist IBC nicht wirklich genau definiert. Alles was "ganz normal" andere Methoden direkt aufruft.

24.06.2010 - 23:50 Uhr

Unit Tests bzw. autom. Testen bzw. TDD hat nicht (!) nur den Zweck, irgendwie Fehler früher zu finden. Das kann ich gar nicht genug betonen.

Das ist mittlerweile auch bei mir angekommen.

Die Liste der Vorteile, die TDD et al. bringt, ist länger. Wenn du also hergehst und nun versuchst auszurechnen, ob sich TDD vom ROI her lohnt, weil du genau weißt, wieviel dich deine Fehler heute kosten und kommst darauf, dass TDD et al. die Entwicklung 13,65% teurer machen würden und deshalb unrentabel wäre, dann hast du TDD et al. leider nicht richtig verstanden und tust ihnen Unrecht.

Ich bleibe dabei: Dich werden keine Zahlen überzeugen. Du wirst es dir immer so hinrechnen können, dass TDD et al. zu teuer sind.

Du schätzt mich da völlig falsch ein. Ich wollte TDD damit nicht auf die harten Zahlen reduzieren. Aber die harten Zahlen müssen trotzdem sein, um objektiv zu beweisen, ob TDD auch tatsächlich etwas bringt. Ich weiss jetzt, auf wieviel zusätzliche Entwicklungszeit ich mich einstellen muss und was - jetzt mal nur auf die Bugs bezogen - ich damit erreichen kann (pessimistisch gesehen, wäre das die Halbierung der Bugs). Wenn ich dazu noch zusätzliche "Bonus-Leistungen" bekomme, dann könnte sich die Testerei vielleicht doch lohnen.

Für die müsstest du dir 1-2 Monate Zeit nehmen und dich ganz auf TDD et al. einlassen. Das würde mich bestimmt zum absoluten Test-Experten machen, aber 1-2 Monate Zeit nehmen ist - zumindest momentan - utopisch. Es werden wohl eher 6-12 Monate werden, in denen ich mich "nebenher" und bröckchenweise in das Thema reinarbeite.

Du siehst es hier im Forum: Die große Mehrheit der Leute setzt auf autom. Tests und bezeugt, dass das Vorteile hat. Das beeinflusst deine Meinung nicht. Weder also Beispiele von anderen noch Zahlen bringen dir etwas. Wir reden hier über Gewohnheiten und Glaubenssätze. Und gegen die kommen nur andere Erfahrungen an.

Ich würde schon sagen, dass mich die Meinungen der Leute hier beinflussen. Ich mache ja keine Umfrage, um die Ergebnisse am Ende einfach zu ignorieren. Das bisherige Umfrageergebnis hat meine Vorahnungen bestätigt. Es gibt eine ganze Menge Leute, die noch keine Tests machen, aber sich bereits mit dem Thema befassen und irgendwann auch automatische Tests machen werden. Die machen das bestimmt nicht alle nur, weil sie irgendwo gelesen haben, dass automatische Tests jetzt Hipp und Cool sind. Dieser Thread hier ist voll von sachlichen Argumenten für automatische Tests. Auf der Gegenseite sieht es dagegen mau aus. Wenn ich mir die Ohren zuhalten wollte, dann würde ich doch keine Fragen stellen, oder?

Wenn du zufrieden bist, dann lass es.

Ich bin eigentlich schon zufrieden. Aber vielleicht bin ich noch viel zufriedener, wenn sich meine Bugs halbieren.

um einen berücksichtigt es nicht die volkswirtschaftliche Komponente. Denn durch einen Fehler entsteht ja auch dem Kunden ein Schaden oder zumindest ein Aufwand. Sich da auf den Standpunkt zu stellen, dass das ja keine Kosten sind, die die eigene Firma tragen muss, mag betriebswirtschaftlich richtig sein, aber es wäre schade, in so engen Grenzen zu denken. Zumal - das wäre mein zweiter Punkt - die Kosten durch Fehler für den Kunden natürlich eine Rolle spielen und sicher auch in die Entscheidung für oder gegen ein Produkt mit einfließen.

Natürlich darf man das alles nicht außer Acht lassen. Da sich das aber schlecht messen lässt, schaue ich erst mal auf das, was sich messen lässt. Die 15% + 5% Angstzuschlag bei Halbierung der Bugs sind okay. Also macht es Sinn, sich näher damit zu beschäftigen. Die "weichen" Vorteile kann ich dann erst durch eigene Erfahrungen überprüfen. Zuerst wollte ich aber wissen, ob ich die Zeit überhaupt investieren will, um diese Erfahrungen zu machen. Das ist nun geklärt.

24.06.2010 - 07:44 Uhr

Hallo zusammen,

ich habe auch noch eine interessante Studie von Microsoft Research zu Thema TDD gefunden: http://research.microsoft.com/en-us/projects/esm/fp17288-bhat.pdf

Wenn ich das und die Aussagen der Links von Ralf und dr4g0n76 auf harte Zahlen reduziere, komme ich dabei auf folgende Ergebnisse:

Durch Einsatz von TDD kann die Anzahl der Bugs um das 2-5 fache reduziert werden. Statt 50 Bugs könnten das dann also nur 25 oder sogar nur 10 Bugs sein, wenn TDD eingesetzt wird. Wie hoch die Ausbeute ausfällt hängt natürlich vom einzelnen Projekt ab. Das war auch in den verschiedenen Studien teilweise sehr unterschiedlich. Aber selbst wenn man passimistisch ist, dann ist die Halbierung der Fehler schon ein Wort.

Dem Gegenüber steht allerdings eine gemessene Verlängerung der Entwicklungszeit (und damit auch höhere Kosten) von 15-35%.

Ob TDD sich "kalkulatorisch" rentiert, hängt also davon ab, wie viel das Doppelte bis Fünffache an Fehlern letztendlich kostet. Wenn die gegenüber TDD überzähligen Fehler weniger als 15% der Gesamtentwicklungskosten an zusätzlichem Aufwand produzieren, dann ist es billiger, ohne TDD zu entwickeln. Wenn die Fehler allerdings mehr als diese 15% zusätzlich kosten, dann ist TDD eindeutig "günstiger".

Jetzt habe ich einen Überblick, was die höhere - durch Tests erreichte - Qualität kostet, bzw. in wie weit sie sogar insgesamt günstiger sein kann. Da muss ich nun erst eine Nacht drüber schlafen.

22.06.2010 - 09:06 Uhr

@dr4g0n76: Danke für die Links!

@ralfw: Ebenfalls, danke für die Links!

Ist sich dein Unternehmen eigentlich heute (!) bewusst, welche Arten von Fehlern in welcher Frequenz gemeldet werden und wie lange ihre Beseitigung benötigt? Denn nur wenn du das heute erhebst, hast du einen Vergleichswert. Wieviel Aufwand fließt heute in eure manuellen Tests? Bitte messen. Wieviel Aufwand fließt in die Behebung von Regressionsfehlern? Bitte messen.

Ja natürlich. Alle Fehler werden in einem Bugtracking-System erfasst. Auch die Lösungen dazu werden erfasst. Die Zeitpunkte, wann was bemerkt und wann was getan wurde und wann welcher Bug nachweislich gelöst wurde, werden dabei auch erfasst. Dies ermöglicht zuverlässige Messung und Auswertung der Daten.

Definiere Nutzen.

Verminderung der Häufigkeit des Auftretens von Fehlern (Bugs).
Reduzierung der Anrufe wegen Bugs bei der EDV-Hotline.
Reduzierung von Kosten, die durch Fehler entstehen (z.B. Buchungsfehler aufgrund von fehlerhaftem Programmcode).
Reduzierung von Zeit/Kosten für die Pflege und Weiterentwicklung vorhandener Software (Stichwort Refaktorisierung).

21.06.2010 - 23:55 Uhr

Außerdem sollte inzwischen TDD state of the Art sein, wie ja hier von anderen auch schon erwähnt wurde.

Nur "weil man das jetzt eben so macht und fertig" werde ich bestimmt nicht nach TDD entwicklen. Ich würde auch keine rosa Flipp-Flopps mit Keilabsätzen tragen, auch wenn das die angesagte Herren-Sommemode werden sollte.

Ich wehre mich einfach gegen diese "Mach es so, dann wirst Du Erfolg haben!" Ideologie.

Ich habe nur gute Erfahrungen mit Unit-Tests gemacht.
Und man schreibt den Code doch etwas anders. Flexibler.

Das deckt sich mit den anderen Aussagen, über implizite Verbesserungen in der Archtiktur, die automatisch gemacht werden, um testbaren Code zu erzeugen. Das ist in Ordnung, warum nicht. Dann hat man Tests + bessere Architketur.
Allerdings lassen sich Verbesserungen in der Architektur auch durch entsprechende Konzepte und Konventionen im Entwickler-Team erreichen. Auch ersetzen Tests nicht die Notwendigkeit sich bei einem projekt über Software-Architektur Gedaken zu machen.

Ich behaupt einfach mal dass Unit-Tests ab einem bestimmten Projektumfang IMMER den Zeitaufwand hinten raus reduzieren.

Kannst Du das auch beweisen? Um wie viel Prozent haben Bugs und Support-Anfragen seit der Einführung von automatischen Tests zurückgegangen? Hast Du (oder jemand anders) das mal gemessen?
Haben die Tests wirklich eine nennenswerte Verbesserung im Verleich zum Aufwand gebracht?

Und dass der produktive Code durch die Unittests besser wird, ist IMHO auch Tastache.

Das ist nur eine rethorische Killerphrase. "Besser" ist sehr schwammig und allgemein. Wenn der Einsatz von Tests sich vorteilhaft auf das Endergebnis auswirkt, dann muss man dies messen können. Ansonsten ist es nur "ein gutes Gefühl". Selbst wenn es dem Entwicklerteam nur ein gutes Gefühl gibt, wüssten dessen positive Auswirkungen (Motivation, Mut zu Refaktorisierungen, etc.) sich auch wieder messbar niederschlagen. Vorrausgesetzt, man kann Änderungen im Gesamtergebnis eindeutig auf die Tests zurückführen. Eine Reduzierung der Bugs könnte auch die kürzliche Gehaltserhöhung der Entwickler oder die neuen ruhigen und klimatisierten Büros herbeigeführt haben.

Deshalb die Frage: Kennt jemand eine unabhängige Studie, welche die effektiven Verbesserungen in Projekten durch automatische Tests gemessen hat?
Bitte keine Fallstudien, in denen einfach verschiedene Leute interviewed wurden und sagen, dass sie jetzt alle glücklicher sind.

Versteht mich bitte nicht falsch. Ich erkenne die Vorteile von automatischen Tests voll und ganz an. Aber ich denke, dass der Aufwand den Nutzen am Ende übersteigt.

Vielleicht sind automatische Tests auch nur in bestimmten Szenarien wirklich rentabel.
Ich kann mir z.B. gut vorstellen, dass Tests in einem Team mit hoher Fluktuationsrate wesentlich mehr bringen, als in einem eingespielten Team. Wenn ich mir vorstelle, dass Teile eines Projekts vielleicht mittels Offshore-Outsourcing ausgelagert werden, dann beginne ich Tests immer interessater zu finden.

Wenn ich aber weder hohe Fluktuation im Team noch Outsourcing habe, dann finde ich die Tests wiederum nicht mehr sonderlich interessant. Ich darf meine Situation deshalb nicht verallgemeinern. Aber andere dürfen das ebensowenig.

20.06.2010 - 14:55 Uhr

Ich würde sogar fast so weit gehen und sagen, dass das der Hauptnutzen von Unittests ist und Fehler entdecken nur eine netter Nebeneffekt ist.

Dann ist der Vorteil der Tests - wenn ich das richtig verstanden habe - dass man gezwungen wird, eine ordentliche Architektur aufzubauen. Wenn man testbare Software schreibt, muss sie in die zu testenden Bestandteile zerlegbar sein. Also erstellt man besser strukturierte Software, um den automatischen Test zu ermöglichen.

@herbivore: Abstimmung korrigiert.

20.06.2010 - 14:27 Uhr

Hallo zusammen,

wenn man der Fachpresse glaubt, dann gehören Unit-Tests zum Guten Ton in der Branche und sollten quasi eine Selbstverständlichkeit sein. Ist das wirklich so?

Ich selbst habe Zeifel am Nutzen von Unit-Tests, wenn man den Aufand ins Verhältnis setzt. Führt der sachgemäße Einsatz von Unit-Tests tatsächlich zu qualitativ hochwertiger Software?

Und wenn ja, gibt es eindeutige messbare Beweise dafür?
Was sind Eure Erfahrungen mit Unit-Tests?

Vielleicht können wir diesen Fragen zusammen sachlich auf den Grund gehen.

Interessant ist in diesem Zusammenhang auch der folgende Thread: Alltag in unserer Branche (?)

20.06.2010 - 12:12 Uhr

Hallo malignate,

der Designer sieht jetzt schon sehr vielversprechend aus. 👍

Das bringt dann doch deutlich mehr, als eine schnöde Baumansicht.

18.06.2010 - 20:32 Uhr

Wer die Kompetenz zum Bau eines Designers hat, der sollte einfach was einfaches zusammenbasteln und mal zeigen. Es geht um ein erstes kleines Featureset, eine erste kurze Iteration.

Naja... werde wohl nicht umhin kommen, selbst was zu basteln 😉

Ich könnte mir vorstellen, dass man auch mit einem recht einfachen Editor recht weit kommt. Konkret denke ich da an eine Baumstruktur. Die enthält Platinen und Komponenten. Jedes Element lässt sich aufklappen und hat einen Unterknoten "Drähte". Darunter kann man die Drähte anlegen. Mit einer mehrspalten Baumansicht a la TreeViewAdv (http://sourceforge.net/project/screenshots.php?group_id=166562&ssid=37269) sollte das grundlegende Übersicht schaffen.

Ganz grob in ASCII-Art dargestellt:


[+] Komponente1
 |
 +---[+] Drähte
 |    |
 |    +--- {Out_Pin1} => {Komponente2.In_Pin2}
 |
 + ...

Sowas ist relativ schnell gemacht und spar Zeit beim verdrahten. Der Verdrahtungscode könnte direkt mit CodeDOM generiert werden.

Was meint ihr dazu, fürs Erste?

18.06.2010 - 12:48 Uhr

Hallo gfoidl,

LatexDraw sieht vielversprechend aus.
Danke für den Tipp.

Gruß

Rainbird

17.06.2010 - 22:53 Uhr

Hallo zusammen,

Frage an alle die gerade mit EBCs experimentieren, oder diese vielleicht schon einsetzen: Wie zeichnet Ihr eure EBC-Schaltpläne?

und mit welcher Software?

Das beste (kostenlose) was ich bis jetzt gefunden habe ist OpenOffice Draw.

17.06.2010 - 22:47 Uhr

Hallo Ralf,

In_ und Out_ finde ich sehr gut. Ich habe mir schon eine Weile beim Benennen der Pins einen abgebrochen. Jeder Pin hatte ein anderes Verb (z.B. send, notify, receive). Dabei liegt in und out so nahe. Ich mag zwar keine Unterstriche, aber in dem Fall kann ich das unter Event-Style á la Button1_Click verbuchen.

Pin-Benennungsproblem gelöst.

17.06.2010 - 00:53 Uhr

Ich verstehe aber noch nicht ganz den Nutzen einer Interface Klasse?

Soweit ich das verstanden habe, wird diese als Proxy Stellvertreter Objekt der Remoting Instanz genutzt. Aber wozu dient das ganze? Wieso nicht direkt die Manager Klasse, statt dem Interface ?

Das ist wichtig fürs Deployment (also das Ausrollen der Anwendung). Die Dienst-Implementierungs-Assembly (also die Assembly in der die Klasse CallManager definiert ist) sollte nicht auf den Client verteilt werden. Der Client darf die Implementierung gar nicht kennen. Damit er aber trotzdem die Methodensignaturen (und damit auch Intellisense beim entwicklen) hat, wird an den Client nur die Schnittstelle ICallManager verteilt. Der Client arbeitet immer mit ICallManager. Niemals mit CallManager.

Wenn Du das so machst, kannst Du auf dem Server Updates fahren, ohne die Clients neu ausrollen zu müssen. Solange die Schnittstelle kompatibel ist!

Ich habe zusätzlich noch eine AppServer.API (wie du) - welche allerdings nur das Call.cs Klassen Objekt beherbergt (was ich momentan etwas überflüssig finde) - du verwendest die API um Server Funktionen zu integrieren und anzusprechen, allerdings soll mein AppServer lediglich die Call Klassen Objekte verwalten.

Macht eine AppServer API bei mir sinn?

Ich würde zunächst sagen nein. Die Call-Klasse ist einen Contract (kein Dienstvertrag wie ICallManager, sondern einen Datenvertrag) und gehört deshalb zusammen mit ICallManager in die Contract-Assembly. Der Client braucht dann nur diese eine Assembly und findet darin alles, was er für die Kommunikation mit dem Server braucht.

Mir ist nicht klar, wie ich auf Client Seite das richtige (CallManager) Objekt als Singleton aktivieren soll oder muss ?!

Singleton-Aktivierung bedeutet, dass es nur ein einziges CallManager-Objekt auf dem Server gibt! Dieses behandelt alle Client-Anfragen. Jede Client-Anfrage geht in einem eigenen Thread ein. Du musst deshalb den CallManager threadsicher programmieren. Bei SingleCall hast Du das Problem nicht, dafür kannst Du keinen Status halten, weil SingleCall aktivierte Objekte nur einen Methodenaufruf lang leben.

Bei Singleton-Objekten nicht vergessen InizializeLifetimeService zu überschreiben und die Lease zu konfigurieren. Wenn ein Objekt unendlich lange leben soll, dann einafch null zurückgeben.


// CallManager-Proxy erzeugen
ICallManager proxy=(ICallManager)Activator.GetObject(typeof(ICallManager),"tcp://localhost:9090/CTI_Integration.Extension.Contracts.ICallManager");

// Call vom Server abrufen (Ich kenne Deine ICallManager-Schnittstelle nicht, aber so könnte es aussehen)
Call call=proxy.GetCall(4711);

16.06.2010 - 08:28 Uhr

Ich gehe davon aus, du meintest das mit deinem Vorschlag für mich genau so wie du in deiner n-Tier Applikation vorgeführt hast? (PN)

So könntest Du das machen. Du kannst es aber auch noch vereinfachen. Services und BusinessComponents kannst Du z.B. auch jeweils in einer Klasse zusammenfassen.

Wo kann ich diese begrifflichkeiten wie "Contract" Klasse und alles eigentlich nachlesen , also wo hast du dir das Wissen hergeholt für die Architektur ? Bücher, Web, Foren, Gespräche mit anderen Entwicklen. Das Übliche.

Fast alles über .NET Remoting findest Du z.B. hier: .NET Framework Developer&#39;s Guide:
.NET Remoting

Das Wort Contract (Vertrag) stammt aus der SOA-Ecke.

Ich verstehe deine Art Umsetzung leider noch nicht ganz, da ich wie erwähnt ja versuche das ganze irgendwie für mich umzusetzen, sehe ich noch nicht so ganz was da am nähesten für mein Beispiel ist.

Du solltest Deinen eigenen Remoting Server aufbauen. Dann weist Du auch, wie alles unter der Haube funktioniert. Dein Server hat dann auch nur die Funktionen, die Du brauchst. Mein Beispiel kannst Du als Orientierung nehmen. Ein Einstieg ist nicht schwer. Ein Remoting-Server braucht in der Minimalversion nur zwei Zeilen Code.

Deine Module sind ja nicht ganz eigenständige Programme, da sie in dem Client geladen werden und aber auch auf die Server API zugreifen.

Ich baue meine Anwendungen stets mit Komponenten.

Wäre eine Umsetzung wie du sie mir vorgeschlagen hast dann wie folgt:

AppServer
-> Server programm GUI oder Konsole
-> CallManager Klasse (MarshalbyRefObj - beinhaltet die genaue Geschäftslogik?)

AppServer API -> ICallManager (kein MarshalbyRefObj) -> Call Klasse [Serializeable]

Jetzt kommt für mich das schwierige ... du hast hier ne Schicht mit den Contracts und Services... Wie würde ich das für mich umsetzen ?!

Windows Client (CTI Anwendung)
-> Windows GUI
-> Referenziert die AppServer API

Der AppServer sollte ein Windows-Dienst oder eine Konsolenanwendung sein.

Ich würde folgende Projekte machen:

Rainbird.AppServer

Rainbird.AppServer.Api

Rainbird.Cti.Services (Geschäftslogik
--> CallManager

Rainbird.Cti.Contracts (Schnittstellen/Verträge)
--> ICallManager
--> Call

Rainbird.Cti.Gu (Benutzeroberfläche)
diese meiner Sache am nächsten war. [/u]

Ich müsste CallManager.cs (in meinem fall) also als Singletone Objekt initialisieren ?

Wenn er Variablen über längere Zeit halten muss, dann Singleton, ansonsten SingleCall.

Sollte die CallManager Klasse in ein eigenes Projekt zur Assembly gebuilded werden, so dass ich diese im AppServer refenziere oder liegt die CallManager.cs im AppServer schon richtig dort?

Eigene Assembly! + Eigene Contract-Assembly. Wie oben erklärt.
AppServer benötigt keinen Verweis! CallManager nur als Remoting-Dienst in der App.config eintragen.

25.05.2010 - 18:39 Uhr

Hallo Phenix,

das geht auch mit Remoting ganz einfach. Du kannst Callbacks verwenden.
Hier ein Beispiel für einen kleinen Client/Server Chat mit Remoting:
http://www.tutorials.de/forum/net-tutorials/77884-remoting-wie-programmiere-ich-einen-chatserver.html

Hier noch eine allgemeinere Implementierung eines zentralen Benachrichtigungs-Dienstes: NotificationService als Erweiterung zu Rainbirds ApplikationServer Beispiel

25.05.2010 - 07:04 Uhr

Hallo phenix,

was willst Du denn genau machen. Vielleicht gibt es eine ganz einfache Lösung.

Eines vorweg: Windows-Fenster über Netzwerk auf einem anderen Computer fernzusteuern ist meistens (nicht immer) kein guter Ansatz.

21.05.2010 - 07:35 Uhr

Hallo Howard,

Access <-> C# ist auch mein täglich' Brot.
Access versteht nur COM, daran ist nicht szu ändern. Es gibt zwar seit Windows XP die Möglichkeit COM-DLLs ohne Registry zu verwenden (Stichwort SxS oder Side-by-Side). Dabei werden die Infos, die sonst in der Registry stehen, in einer XML-Manifestdatei gepflegt. Leider unterstützt Access diese SxS-Geschichte nicht wirklich. All meine Versuche in dieser Hinsicht sind gescheitert. Also zurück ans Reißbrett.

Man kann die COM-Verweise nicht verhindern, aber drastisch reduzieren. Statt Deine Funktionalität direkt für COM-Interop zu veröffentlichen, baust Du ein allgemeines Kommunikationssystem, welches von Access und C# gleichermaßen genutzt wird, um Befehle und Nachrichten auszutauschen. Die eigentlichen C#-Assemblies, welche die Funktionalität implementieren, werden von dieser Kommunikationsschicht per Reflection geladen und aufgerufen. So wird XCopy-Deployment möglich (vorausgesetzt, die Kommunikationsschicht wurde einmal unter Admin/Hauptbenutzer installiert).

Aus C# heraus könnte sich sowas etwa so anfühlen: (Nachfolgender Code ist nur Pseudeo-Code!)


// Access-Formular starten
AccessObject accForm = AccessInteropHelper.OpenFom("Article");

// Methode am Formular aufrufen
bool success = (bool)accForm.InvokeMethod("LoadArticle",4711);

// Komplete Daten von Access-Objekt abrufen
ADODB.RecordSet rs=(ADODB.RecordSet)accForm.InvokeMethod("GetArticlePrices");

// Recordset in .NET DataTable umwandlen
DataTable table = AccessInteropHelper.ConvertRecordSetToDataTable(rs);

Aus Access heraus könnte sich das so anfühlen:


' Interop-Kommunikationsmanager erstellen
Dim objDotNetInterop As Rainbird.DotNetInteropManager
Set objDotNetInterop=new Rainbird.DotNetInteropManager

' C#-Formular öffnen
Dim objDotNetForm As Rainbird.DotNetObject
Set objDotNetForm=objDotNetInterop.CreateObject("Rainbird.Example.dll","Rainbird.Example.LoginForm")

' Methode an C#-Formular ausführen
Dim objResult As Rainbird.DotNetObject
Set objResult=objDotNetForm.InvokeMethod("ShowDialog")

' Konkreten Wert auslesen
Dim lngDialogResult As Long
lngDialogResult  = objResult.GetValueAsInt

Vor Allem ist es sehr wichtig, sämtliche Interop-Mapping-Geschichten aus den Funktionalen C#-Klassen komplett rauszuhalten! Also z.B. nicht in .NET Objekten plötzlich mit ADODB.RecordSets arbeiten, nur weil das von Access zu geliefert wird. Stattdessen Wrapper-Klassen schreiben und diese in eine separate Assembly auslagern. Die Interop-Kommunikationsschicht konsumiert dann diese Wrapper.
Ob Access-seitig auch Wrapper erstellt werden müssen hängt davon ab, ob Access schnellst möglich komnplett abgelöst werden soll, oder ob es - warum auch immer - noch längere Zeit beibehalten werden soll.

Dieses Konzept ist praxiserbrobt. Ich kann damit sogar .NET Windows.Forms als MDI-Childs im Access-Anwendungsfenster laufen lassen. Das ermöglicht eine fließende Migration von Access nach .NET. Die Formulare können Stück für Stück durch Access-Formulare ersetzt werden. Die .NET Formulare fühlen sich für den Endanwender nicht als Fremdkörper an, die sie sich wie Access-Formulare verhalten.

Nur falls das für Dich interessant ist.

09.05.2010 - 12:24 Uhr

Hallo winmike,

ich glaube Martin Fowler hat eher gemeint, dass man Objekte, wie sie in einer klassichen Objektorientierten Anwendung vorhanden sind, nicht einfach irgendwie übers Netzwerk geschickt werden sollen. Er hat nicht gemeint, dass die übertragenen Daten nicht durch Objekte repräsentiert werden dürfen. Das ginge gar nicht, da in C# alles ein Objekt ist.

Gigaspaces verstehte ich als Daten-Drehsscheibe in Richtung EAI gehend. Damit lassen sich einfach verschiedene Anwendungen verdrahten.

09.05.2010 - 12:04 Uhr

Hall freundblase,

kannst Du den Code-Schnipsel posten, der den SQL-UPDATE ausführt?
Genrell sind SQL float und C# double verträglich. Da sollte es keinen Genauigkeitsverlust geben.

09.05.2010 - 12:03 Uhr

Hallo bonzy,

ohne Code kann ich Dir nicht direkt weiterhelfen. Hier findest Du eine fertige Chat-Anwendung in C#, die mit Sockets implementiert ist: http://www.codeproject.com/KB/IP/TCPIPChat.aspx

Das sollte also ähnlich sein, wie in Deiner Anwendung. Vielleicht erkennst Du den Fehler, wenn Du Deinen Code damit vergleichst.

Wichtig! Wenn Du Netzwerkanwendung entwickeln willst, solltest Du gut über die Funktionsweise von Netzwerken und insbesondere des TCP/IP Protokolls Bescheid wissen. Dazu ist folgender Linj interessant: http://www.elektronik-kompendium.de/sites/net/0812271.htm

09.05.2010 - 02:30 Uhr

Hallo bonzy,

warum programmierst Du die Kommunikation zu Fuß mit Sockets? Das geht mit WCF oder Remoting viel einfacher. Diese Frameworks nehmen Dir fast die ganze Arbeit der Netzwerkkommunikation ab.

06.05.2010 - 05:55 Uhr

Hallo zusammen,

eine andere, sehr komfortable Möglichkeit, gleichzeitige Lese und Schreibzugriffe zu managen sind Transaktionen. Viele verbinden das automatisch mit Datenbanken. Dem ist nicht so. System.Transactions lässt sich mit beliebigen Daten einsetzen.

06.05.2010 - 01:24 Uhr

Hallo zusammen,

ich habe mich mit den Lizenzgeschichten auch etwas beschäftigt.

Das ActionPack kann nur EIN MAL pro Firma/Konzern ausgestellt werden. Damit sind sämtliche Filialen (auch im Ausland) und Außenbüros eingeschlossen, die vollwertige Töchter sind. Ich kann also nicht ein Action Pack für die Zentrale Hamburg und ein weiteres für das Verkaufsbüro Frankfurt ordern. Falls ich es doch irgendwie hinbekomme, ist das zweite Action Pack illegal.

Beim ActionPack wäre noch zu beachten, dass man jedes Jahr einen Fachlichen Test ablegen muss, um das Abo verlängern zu können (der Test ist zwar pippifax, aber man muss ihn innerhalb einer Frist ablegen). Außerdem muss man Partner sein, um das ActionPack zu bekommen. Das ist zwar ganz einfach und kein Problem. Allerdings muss man Microsoft auf Wunsch Einblick in die eigenen Geschäftsbücher (insofoern Geschäfte in Zusammenhang mit Microsoft-produkten getätigt wurden) gewähren. Das ist grundsätzlich wichtig zu wissen. Für die kleinste Partnersufe "Registered Memeber" muss mein keine Kompetenzen vorweisen und benötigt auch keine Punkte. Für das Actionpack reicht die Stufe "Registered Member" aus.

Ab dem 24.Mail 2010 gibt es auch ein spezielles ActionPack für Entwickler, welches MSDN Subscription und Visual Studio 2010 für 3 Entwickler enthält und zusätzlich einige produktiv nutzbare Lizenzen für Exchange, Office & Co. Infos dazu gibts hier: https://partner.microsoft.com/germany/40132997
Das ist ideal für kleine Software-Firmen, da die produktiv nutzbaren Lizenzen auch für Vertrieb/Buchhaltung/Verwaltung etc. eingesetzt werden können.

TechNet erlaubt keine Produktivnutzung von Windows- Office & Co.! TechNet Lizenzen sind nur für Test und Produktevaluierung. Im gegensatz zu den meist auf 180 Tage begrenzen kostenfreien Eval-Versionen haben TechNet-Eval-Versionen keine zeitliche Begrenzung.

MSDN erlaubt auch nur die Nutzung für Test und Entwicklung. Ausnahme ist die produktive Nutzung von Office, aber erst ab MSDN Premium Subscription! Man darf MSDN Lizenzen zwar 10 Mal aktivieren. Aber die Installationen dürfen nur von dem Benutzer genutzt werden, für den die MSDN Subscription lizenziert ist. Mit MSDN Keys installierte Produkte dürfen von mehreren Benutzer gemeinsam genutzt werden, wenn alle diese Nutzer eine MSDN Subscription haben, die das betroffene Produkt enthält. Ich darf also z.B. nicht bei 10 Entwicklern eine MSDN Premium und neun MSDN Pro kaufen und bei allen 10 Entwicklen Office 2007 installieren. Ich darf vor allem keine Produkte mit MSDN Key für Benutzer installieren, die keine MSDN Subscription haben.

MSDN wird für gewöhnlich immer für 2 Jahre abgeschlossen. MSDN Professional kostet ca. 1500 EUR für 2 Jahre pro Entwickler und MSDN Premium ca 3000 EUR für 2 Jahre pro Entwickler. Bei den größeren Edition habe ich die Preise nicht im Kopf.

Wichtig zu wissen ist auch, dass MSDN für bestimmte Produkte auch Volumenlizenz-Versionen enthält. Diese brauchen nicht aktiviert zu werden. Das eigent sich besonderns für Windows- und Office, das z.B. für Testzwecke dauernd neu installiert wird. Die Volumenlizenzschlüssel können nicht über die MSDN Seite angerufen werden, sondern müssen über Microsoft Volume Licensing abgefragt werden.

Visual Studio 2010 ohne MSDN enthält definitiv keine Team Foundation Server Zugriffslizenz (CAL).

Die wichtigste Änderung an Visual Studio 2010 mit MSDN ist, dass der vollwertige Team Foundation Server bereits bei Visual Studio 2010 Professional mit MSDN enthalten ist. Früher musste man den Server separat lizenzieren bzw. die größte MSDN-Edition kaufen. Bei den kleineren Editionen war nur die auf 5 User abgeriegelte Workgroup Edition des TFS enthalten.

Die seltsamen Team-Rollen wurden ganz abgeschafft. Wer so eine VS 2008 Team Rolle gekauft hat, wird - soweit ich weiss - automatisch hochgestuft, wenn er innerhalb eines bestimmten Zeitraums den Vetrag verlängert hat.

Soweit mein Wissen über MS Entwickler-Lizenzen. Vielleicht war ja der eine oder andere Punkt dabei, den ihr noch nicht gewusst habt. Wenn nicht, dann war das eben die große Zusammenfassung von Susi 😉.

03.05.2010 - 09:41 Uhr

Hallo daniel,

Für Variante a) spricht, dass die Dienste nicht Code technisch voneinander abhängig sind. Gegen Variante b) spricht, dass der Artikeldienst von der Geschäftspartnerverwaltung abhängig wäre. Ob das problematisch ist, oder nicht kann man pauschal nicht beantworten. Aber es ist eine Abhängigkeit.

Variante c) könnte so aussehen:

Die Verknüpfung von Artikeln zu Kunden in eine separate Tabelle auslagern und einen separaten Dienst für die Abfrage, Auflösung und Pflege dieser Verknüpfungen bereitstellen, der sowohl den Artikeldienst als auch den Geschäftspartnerdienst konsumiert.
Dann muss man sich allerdings noch fragen, wie das Ganze im Client abgebildet wird? Separates Formular für die Pflege von Kundenspezifischen Artikeln? Oder ein UserControl welches im Artikelstamm-Formular eingbettet wird?

Eine pauschale Antwort gibt es nicht. Es gibt für und gegen alle drei Varianten Argumente. Die Vor- und Nachteile zu kennen sollte aber helfen, die jeweils beste Variante für das konkrete Projekt auszuwählen.

27.04.2010 - 18:28 Uhr

Hallo Y_Pedro,

die einfachste Lösung besteht darain, den gewünschten Vorgang mit dem Makro Recorder von Word als VBA Code aufzuzeichnen und den VBA-Code dann in C# zu übersetzen.

In Deinem Fall kannst Du im aufgezeichneten VBA Code nachsehen, was Du falsch gemacht hast.

27.04.2010 - 18:25 Uhr

Hallo JunkyXL,

die Events werden nicht gefeuert, da die COM-Wrapper-Objekte von denen diese Events gefeuert werden, ihren Gültigkeitsbereich längst verlassen haben.

Um den Problem zu beheben solltest Du folgendes tun:*Das var weglassen und stattdessen mit den eindeutigen COM-Interfaces bzw. Klassen arbeiten *Die Objektvariable document als klassenweit als Feld anlegen (Damit dauerhaft ein Verweis auf das Word-Dokument erhalten bleibt *Beim Dispose Marshal.ReleaseComObject für die Variable document aufrufen

Außerdem solltest Du generell keine Ketten bilden!! Das hat bei COM-Interop unangenehme Seiteneffekte. Diese Zeile solltest Du ändern:


// So nicht!
var document = app.Documents.Open( .... );

Besser ist folgender Ansatz:


// Sondern besser so:
Documents documents=app.Documents;
DocumentCalss document = documents.Open( .... );
Marshal.ReleaseComObject(documents);

27.04.2010 - 17:11 Uhr

Dort muss man relativ umständlich über UnixDomainSockets seine FileDeskriptoren neben den Daten als "Ancillary Data" zu einem DatenPaket mittels sendmsg übertragen. (Mein jetziger Weg) Und das macht Remoting eben nicht mit 😉

Damit Du es über Sockets übertragen kannst, muss Du es vorher in ein byte[] serialisieren. Über Sockets werden nur Bytes übertragen. Du kannst ein byte[] aber auch mit Remoting übertragen. Möglicherweise musst Du die Serialisierung vorher manuell durchführen, das ist aber kein Beinbruch (ca. 2 Zeilen Code). Ich verstehe deshalb nicht, warum die Datenübertragung mit Remoting nicht klappen sollte?

27.04.2010 - 08:17 Uhr

Hallo zommi,

wenn ich Dich richtig verstanden habe, möchtest Du, dass Remoting bzw. WCF den selben Socket nutzen, wie Deine vorhandene manuelle Implementierung auf Socket-Basis.

Out-of-the-box funktioniert das nicht, da sowohl WCF als auch Remoting ihre benötigten Sockets/Pipes unter der Haube selbst verwalten. Du hast von außen keinen Einfluss darauf, welcher Socket verwendet wird und wann dieser wieder geschlossen wird.

Es gibt aber sowohl bei Remoting als auch bei WCF die Möglichkeit eigene Kanaltypen und andere Erweiterungen zu schreiben. Remoting ist im allgemeinen sehr viel leichtgewichtiger. Der Aufwand sollte sich bei Remoting in Grenzen halten. Hier ein Beispiel für einen benutzerdefinierten Remoting-Kanal: http://www.winsocketdotnetworkprogramming.com/clientservernetremotingnetwork12f.html
Ob Du da Deinen bestehenden Socket wirklich mit rein wursteln kannst, weiss ich nicht. Hab selber noch keinen eigenen Kanal geschrieben. Ich hätte dabei großes Bauchweh.

WCF würde ich nur empfehlen, wenn folgende Punkte eine Rolle spielen:*Interoperabilität (SOAP, etc.) *Kommunikation übers Internet (evtl. durch Firewalls) *Notwendigkeit von HTTPS ohne IIS verwenden zu müssen

Im Vergleich zu Remoting ist WCF ein umständlicher Kram. Allerdings ein sehr mächtiger umständlicher Kram.

Andere Frage, warum verschickst Du nicht auch Deine Handles mit Remoting? Oder muss Dein Load-Balancer direkt mit unmanaged Code kommunizieren (dann geht das natürlich nicht)? Alles was Du über Sockets schicken kannst, kannst Du auch über Remoting schicken. Du hättest dann eine einheitliche Technologie.

26.04.2010 - 08:05 Uhr

Hallo Mazo,

wenn ich das richtig verstanden habe, möchtest Du ein Fenster fernsteuern. TCP-Sockets sind dafür nicht die Erste Wahl. Mit Remoting würdest Du schneller bessere Ergebnisse erzielen.

Hier siehst Du, wie einfach sowas mit Remoting realisiert werden kann: Remoting-Helfer

26.04.2010 - 08:01 Uhr

Hallo leppenraub,

Remoting verwendet unter der Haube auch Sockets. Es wird damit deshalb nicht besser und nicht schlechter funktionieren. Natürlich hast Du mit Sockets alle Aspekte der Kommunikation selber unter der vollen Kontrolle. Bei Remoting ist das Meiste vorgegeben und Du kannst nur an bestimmten Stellschrauben drehen.

Dafür bietet Dir Remoting aber auch jede Menge Komfort, wie automatisches (De)Serialisieren, Objektlebenszeitverwaltung, verschiedene Aktivierungsarten, Saubere Multithreading-Implementierung (alleine das ist es schon wert, es nicht manuell mit Sockets zu bauen) und Zusatzdienste wie Sicherheit und CallContext.

Man kann es nie pauschal sagen, aber erfahrungsgemäß lohnt sich die viele Arbeit mit Sockets nicht, wenn man auch ein fertiges Kommunikationsframework verwenden könnte. Wenn Dir Remoting zu viel vorgibt und Du eher ein "Kontrollfreak" bist, dann wirst Du vielleicht auch eher mit WCF glücklich, als mit Remoting. Da hast Du wesentlich mehr Stellschrauben und kannst viel näher am System arbeiten, als mit Remoting. Dafür ist WCF aber auch viel komplexer.

25.04.2010 - 23:17 Uhr

Hallo zusammen,

dann klinke ich mich jetzt mal ein, wie der-schlingel ja schon prophezeit hat 😉.

Die Lösung ist ganz einfach. Auf Systemen mit mehreren Netzwerkkarten must Du die zu verwendende IP-Adresse in die Channel Property "machineName" schreiben. Dies kannst Du entweder programmatisch beim erzeugen des Channels tun (die Channel Properties werden als Hashtable übergeben) oder per App.config.

Hier die entsprechende Seite der MSDN Remoting Dokumentation: MSDN: Remoting Kanalkonfiguration

P.S. Hab das selber noch nie benutzt, sollte aber so funktionieren.

24.04.2010 - 11:25 Uhr

Hallo Wyatt,

Welche Gründe sprechen aus deiner Sicht gegen das Hosting im IIS? *Nur der vergleichsweise lahme HttpChannel nutzbar *Hoher Deploymentaufwand (man kann seine Anwenung nicht per einfachem Setup ausrollen, wenn beim Kunden noch kein IIS aufgesetzt und richtig konfiguriert ist) *Setzt teueres Server-Betriebssystem vorraus, was meiner "one size fits it all" Philosophie wiederspricht (ich will meine Software u.U. auch auf Windows XP Home installieren können) *Infrastruktur von IIS ist im Rahmen von .NET Remoting-Anwendungen nicht ohne weiteres erweiterbar

IIS ist deshalb kein schlechter Webserver, aber er ist nicht mein bevorzugter Host für Remoting. Ich verwende meistens Konsolenanwendungen, die sich entweder als solche direkt verwenden oder als Windows-Dienst installieren lassen. Letzteres ist in Produktiv-Umgebungen üblicher.