Laden...
Avatar #avatar-1775.jpeg
norman_timo myCSharp.de - Member
Dipl.-Ing. (BA) Informationstechnik Wald-Michelbach (Odw) Dabei seit 13.07.2004 4.506 Beiträge
Benutzerbeschreibung

Forenbeiträge von norman_timo Ingesamt 4.506 Beiträge

05.02.2010 - 14:03 Uhr

Hallo zusammen,

interessantes Thema, das mir auch einmal untergekommen ist. Wir haben es damals ohne Anwalt "gewagt".

Folgendes halte ich für unproblematisch:
Daten in einem Format XY liegen auf der Platte. Du analysierst Die Datenstruktur auf Dateiebene und greifst dann auf die Daten zu (und machst irgendwelche Verarbeitungen damit). Sollte sich das Dateiformat irgendwann ändern, so wird Dein Programm plötzlich Probleme mit dem Auslesen haben. So weit, und unter der Annahme, dass die Daten selbst urheberrechtlich nicht angetastet sind, halte ich das für unproblematisch.

Problem ist, wenn Du Daten manipulativ verarbeitest und dann direkt in der Datei Änderungen vornimmst. Nicht weil die Daten damit verändert werden, weil sonst das Originalprogramm seine Garantie und Supportansprüche verlieren könnte. Wenn der Betreiber feststellt, dass Fremdsoftware an den Daten gespielt wurden...

Wir sind das Risiko eingegangen, dass Daten kaputt gehen können, das hat aber der Kunde gewusst und hat selbst so entschieden...

Grüße
Norman-Timo

14.01.2010 - 09:07 Uhr

Hallo xforfun,

Es gibt Stellen, da arbeite ich mit Bildern auf der HDD.

So lange es nur lesend ist, dann kann man beim Öffnen darauf achten, dass es nur lesend geöffnet wird, da sollte es keine Schwierigkeiten geben.

Wenn es auch schreibend (bearbeitend) ist, dann sollte hier ein lock ausreichen, hier würde ich ein lock-Objekt nehmen, das den eindeutigen voll qualifizierten Dateinamen enthält, das ist eindeutig.

Oft ist Mutex zu hoch gegriffen, kann aber sein, dass es in Deinem Anwendungsfall Sinn macht, das kann ich so aus der Ferne nicht beurteilen.

Grüße
Norman-Timo

13.01.2010 - 11:38 Uhr

Hallo zusammen,

wie meine Vorredner schon beschrieben, halte ich Schichtentrennung und Architekturdesign á la MVC etc auch für 2 paar Schuhe, die zunächst einmal nichts miteinander zu tun haben.

Meinem Verständnis nach sorgt die Schichtentrennung dafür, dass man die Applikation in mehrere Teile aufteilt, die man dann verteilen kann (z.b. auf mehrere Prozesse / Rechner). Sinnvollerweise macht man eine Schichtentrennung dort, wo es Aufgabentechnisch auch am leichtesten realisiert werden kann, also klassisch GUI, BL und DAL.
Man könnte es streng genommen aber auch anders aufteilen, z.B. so dass ein Fenster-Objekt von der GUI vom entfernten Server geholt werden muss (was unpraktisch aber nicht unmöglich ist).

Die Design-Patterns (MVC etc.) sorgen dafür, dass Software wartbarer gemacht wird. So wird die Applikation ganz genau nach Aufgaben aufgeteilt. Diese Aufteilung kann man dann im Schichtenmodell unterbringen muss man aber nicht.

Grüße
Norman-Timo

12.01.2010 - 10:25 Uhr

Hallo zusammen,

die konkrete Frage, die sich mir stellt ist die: Welche Daten werden "zeitgleich" verändert.

Wenn es sich ausschließlich um Datenbank-Daten handelt, so kann man dort sehr einfach mittels Transaktionen und deren Levels eine Synchronisation erreichen ohne dass man großartig im Quellcode etwas berücksichtigen müsste (mal Fehlerbehandlung im Transaktionsfehlerfall abgesehen).

Wenn es sich um .NET Daten handelt (Werte im Speicher in Klassen/Strukturen), so wird man mittels "lock" schon einiges erreichen können. Ein Singleton ist in aller Regel nicht unbedingt vonnöten, kann aber verwendet werden. Wichtiger sind wohl die so genannten "Factories".

Geht es um Daten auf der Platte, dann sollte man sich wirklich Gedanken machen, ob man das nicht anders lösen kann. Das wäre dann extrem unangenehm und wahrscheinlich das komplexeste Szenario.

Grüße
Norman-Timo

12.01.2010 - 10:19 Uhr

Hallo zusammen,

hab jetzt die Google Treffer nicht angeschaut, ob folgendes dabei war, aber ich finde folgendes absolut genial:

Codeproject - Command line argument parser

Ich habe lediglich den Quellcode so umgestellt, dass ein Dictionary (Generics) verwendet wird, und dass der Code in einer Methode ausgeführt wird anstatt im Konstruktor, ist aber Geschmackssache.

Grüße
Norman-Timo

11.01.2010 - 10:15 Uhr

Hallo zusammen,

für mich gilt das gleiche wie jedes Jahr, ich nehme mir immer den gleichen Vorsatz vor:

Ich möchte immer dann mich ändern, wenn ich es für angebracht halte (also nicht auf einen speziellen Termin hin).

[also handhabe ich es wie einige Vorredner vor mir]

Grüße
Norman-Timo

07.12.2009 - 08:47 Uhr

Hallo zusammen,

kleines_eichhoernchen hat schon die Möglichkeiten aufgezählt. Ich wollte nur folgende Informationsquelle hinzufügen:

Microsoft Support - Lesen von XML Streams

Grüße
Norman-Timo

03.12.2009 - 08:49 Uhr

Hallo zusammen,

bevor nun das in einen Multithreading Krieg ausbricht folgende Aussagen:

Es ist richtig, dass ein Prozessor nur einen Thread bearbeiten kann.
Es ist also auch folgerichtig, dass gleichzeitig nur so viele Threads laufen können wie es Prozessoren gibt.
Es ist aber meiner Meinung nach überhaupt nicht gegeben, dass eine Anwendung langsamer läuft, wenn sie nicht genauso viele Threads wie CPU's verwendet (also mehr oder weniger). Das hängt ganz stark davon ab, was der Thread macht, in wie weit es atomare Operationen sind und ob Threads nicht sich selbst schlafen legen etc.

Wenn wir schon beim Besipiel Ping sind. Es ist durchaus denkbar (alles Theorie, also nicht nachgewiesen oder überprüft), dass ein Thread damit startet, den Ping abzusetzen, sich dann aber bis zu einer Antwort schlafen legt. Nehmen wir mal an, dass eine Ping-Antwort 30 ms dauert. Derweil kann ein Thread-Contextwechsel stattfinden und ein weiterer Ping abgesetz werden. Somit wäre die Theorie, dass Multi-Threading-Anwendungen, die mehr Threads als CPUs verwenden langsamer laufen widerlegt.

Also die Quintessenz ist hier: Multithreading ist ein sau-komplexes Thema, bei dem man nie pauschalisieren kann. Es hängt immer vom Anwendungsfall, von der Hardware und von der implementierten Logik ab.

@mrdjoker: Deshalb mag ich solche Berechnungen von Dauerangaben im Multithreading-Context überhaupt nicht. Einmal der Virenscanner zwischendrin (der in aller Regel eine höhere Priorität hat), und alle Berechnungen sind hinfällig.

So, nun war das Ausgangsthema aber Datenbanken, dachte ich zumindest.

Grüße
Norman-Timo

03.12.2009 - 08:37 Uhr

Hallo LarsThorwald,

kann es sein, dass du die Pfadangabe im Debugger verfolgst? Der zeigt Dir nämlich alles "Escaped" an, d.h. ein "C:\Temp" würde er als "C:\Temp" darstellen.

Kann es also sein, dass Du überhaupt keine Ersetzung vornehmen musst?

Ein Path-Objekt enthält in aller Regel nur syntaktisch korrekte Pfade, da dürfte normalerweise ein "\" gar nicht vorhanden sein.

Grüße
Norman-Timo

30.11.2009 - 08:42 Uhr

Hallo ErfinderDesRades,

klar kann man da was machen, man kann VS selbst debuggen (und somit den Designer). Siehe hier: Fail to create component / Not marked as serializable

Das ging zumindest mit VS2005, sollte aber meines Erachtens auch mit VS2008 gehen.

Mit dieser Vorgehensweise konnte ich bisher immer meine eigenen Controls debuggen, vom Drag-In aus der Toolbox inkl. zur Laufzeit.

Grüße
Norman-Timo

16.11.2009 - 13:13 Uhr

Hallo Kuchiki,

naja es kommt auf das Projekt an. Sollte es sich um hauptsächlich Backbone Komponenten ohne grafische Oberfläche sein, dann einfach Quellcode mit VS konvertieren lassen neu kompilieren (Fehler, z.B. Obsolete Fehlermeldungen beheben) und gut ist.

ASP.NET Projekte würde ich neu konzipieren und dann explizit schauen, ob und welche Codeteile ich übernehme, da ist so viel passiert zwischen 1.x und 3.5, da liegen Welten dazwischen.

WinForms Projekte: Das kommt darauf an, was man haben möchte. Wenn man mit der "alten" WinForms Anwendung zufrieden ist, dann genügt eine Portierung. Sollten viele Win32 API Zugriffe realisiert sein, dann würde ich schauen, ob es nicht inzwischen im Framework .NET Klassen dafür gibt.

Allgemein:
Es sind z.B. Generics hinzugekommen, ebenso die ganzen Dinge wie WPF, WCF etc. Das sind Komponenten, bei denen ein Einsatz sich echt lohnt. Von daher würde ich mir jederzeit den Aufwand in Kauf nehmen, und schauen, was es neues gibt, und wo man in der alten Software das sinnvoll einsetzen könnte.

Eine 1:1 Portierung ist meist ungenügend, so hab zumindest ich bisher immer die Erfahrung gemacht.

Grüße
Norman-Timo

03.11.2009 - 16:42 Uhr

Hallo zusammen,

konnte man das Runden nicht immer mittels:


double d= 2.5;
int roundedVal = Math.Round(d+0.5);

ermitteln?

Grüße
Norman-Timo

29.10.2009 - 09:51 Uhr

Hallo Junky,

public bool IsMatch(string name)  
{  
    return (IsIncluded(name) == true) && (IsExcluded(name) == false);  
}  

Das kann aber unter Umständen sogar Sinn machen. Wenn intern 2 Listen geführt werden (inc und exc). Ähnlich wie bei Firewallregeln, die expliziten Angaben vor impliziten Angaben überprüfen.

Aber ich gehe jetzt einfach mal davon aus, dass das hier nicht der Fall ist, dann ist diese Abfrage natürlich doppeltgemoppelt.

Grüße
Norman-Timo

19.10.2009 - 09:24 Uhr

Hallo zusammen,

wenn man als Softwareentwickler erfolg haben will, dann sollte man sich nicht auf eine einzelne Plattform/Technologie konzentrieren. Klar kann man (und muss man) Schwerpunkte setzen.

Nehmen wir mal an, man ist ein .NET Spezialist, dann stellt sich zumindest mir die Frage, wie lange gibt es noch .NET, einen Beruf übt man in aller Regel mindestens 40 Jahre aus, ich will nicht wissen, was in 20-30 Jahren aktuell ist.

Ich finde, als Softwareentwickler hat man dann Erfolg, wenn man sich mit Softwareengineering und Softwarearchitektur beschäftigt. Es ist viel wichtiger Softwareentwicklungsprozesse zu verstehen, zu etablieren und zu verbessern. Teamfähigkeit, Flexibilität und Einsatzbereitschaft sind die Eigenschaften, die zum Erfolg führen.

Embedded Software ist deshalb so attraktiv, weil sich viele Entwickler nicht mehr mit der eigentlichen Hardware beschäftigen. Java und .NET fördern die Hardwarenähe auch nicht gerade, weshalb hier dann Spezialisten gefragt sind. Aber auch der Embedded Bereich verändert sich. Wo früher z.B. auf Handys Symbian und Java lief ist heutzutage auch Windows und .NET anzutreffen. Selbst Getränkeautomaten haben Windows als Betriebssystem installiert (ob das gut oder schlecht ist, darüber kann man sich nun streiten, ist aber nicht meine Intension).

Ich denke auch, dass man seine Branche wählen sollte, denn die ist auch von einem beruflichen Erfolg abhängig. Ich würde die Medizin und Healthcare, sowie Arzt- und Apothekenbranche als vielversprechend halten. Aber auch Banken haben aktuell dringenden Bedarf sich die ollen Softwarestrukturen zu erneuern.

Alles oben gesagte spiegelt nur meine eigene Meinung wider.

Grüße
Norman-Timo

09.10.2009 - 06:24 Uhr

Hallo FastGarrett,

das ist meines Erachtens kein Problem zwischen Delphi und .Net (naja ein bisschen vielleicht doch). Ich muss hier mal etwas mehr ausholen:

Betrachten wir zunächst die Datenbank:

  • DBase ist eine sehr alte Datenbank. Die ersten Versionen waren reine Dateiendatenbanken, ähnlich wie bei MS Access auch heute. Wie der aktuelle Stand aussieht weiß ich ehrlich gesagt nicht. Wenn Du aber sagst, dass hier direkt auf Festplatte und Records zugegriffen werden kann, dann wäre das definitiv vergleichbar.
  • MS SQL Server (Express ist nur limitiert gegenüber der Vollversion, arbeitet aber genauso) ist aus heutiger Sicht eine vollwertige Datenbank, die über SQL angesteuert wird.

Unterschiede sind hier in Folgenden Bereichen deutlich zu spüren:
Versuche mal mit einer Dateiendatenbank im Multi-User und Multi-Threaded Umfeld zu verwenden. Da kommen Dateidatenbanken schnell an Ihre Grenzen. Ebenfalls werden Dateidatenbanken bei Tabellenverknüpfungen und Filterungen deutlich langsamer. Das sollte im SQL Server erheblich schneller gehen.

Betrachtung der Programmierplattform:
Delphi arbeitet wohl Deiner Aussage nach mit Recordsets, .NET bietet hier eine weitere Abstraktion, das ADO.NET. ADO.NET liest Datenbankabhängig zunächst die Struktur der Datenbank aus (Abfragebezogen) und generiert im Speicher die so genannten DataSets, die wiederum aus DataTables und diese dann DataRows beinhalten. Ein direkter Zugriff auf die Daten ist mittels ADO.NET nicht möglich. Somit ist auch das Arbeiten mit RecordSets nicht möglich. Dafür garantiert diese Arbeitsweise transaktionale Sicherheit und eine Abstraktion der Daten (sollte damit auch flexibler in der Anbindung verschiedenster Datenquellen sein).

Wie bekommt man in Deinem Anwendungsfall eine Performanceverbesserung hin?
Es gibt mehrere Möglichkeiten. Du könntest z.B. auf ADO.NET verzichten und noch die veraltete Technik DAO verwenden, nur weiß ich überhaupt nicht, ob das mit dem SQL Server funktioniert und ich würde solch eine Technik nicht mehr einsetzen. Man kauft sich durch das Recordbasierte Arbeiten zu viele Nachteile ein.
Besser ist es eine Intelligenz bei der Dateninitialisierung einzubauen. 1 Mio Datensätze kann kein Mensch überblicken und schon gar nicht gleichzeitig darstellen. Deshalb ist mein Vorschlag immer nur die Datensätze zu holen, die einmal direkt sichtbar werden, und schon als Vorbereitung die, die per Useraktion als nächstes angezeigt werden können (z.B. die nächsten 10, die vorigen 10, die allerersten 10 und die allerletzten 10 Datensätze) [hängt von der UI Gestaltung ab)

Du könntest hier z.B. für die Performanceunterschiede folgendes ausprobieren:
Versuche mal mit Delphi und DBase einen Filter laufen zu lassen (auf die 1 Mio Datensätze). Sagen wir mal es gibt eine Spalte "Nachname". Du möchtest jetzt alle Datensätze sehen, die mit "ler" enden, wie z.B. "Mueller" oder "Keller" etc. So etwas solltest Du dann mal vergleichen mit SQL Server und ADO.NET.

Ansonsten kann man Dir hier auch sicherlich konkret in einzelnen Performanceoptimierungen zur Seite stehen.

Viele Grüße
Norman-Timo

Edit: Zu früh am Morgen, deshalb Grammatik- und Rechtschreibfehler

08.10.2009 - 21:32 Uhr

Hallo zusammen,

eine der besten und vollständigsten C# Freeware FTP Komponente die ich bisher gesehen habe:
BytesRoad.NetSuit Library 2.0

Grüße
Norman-Timo

08.10.2009 - 16:07 Uhr

Hallo Gremgiz,

ob Du eine Kopie von WinForms erstellen / produzieren kannst weiß ich ehrlich gesagt nicht. Habe auf die schnelle nur Codeproject - Clone/Serialize/Copy WinForm gefunden, wahrscheinlich hilfts.

Aber Du kannst initial die Form mittels "new MyForm()" erstellen lassen und Dir die Form dann in einer Variablen vorhalten. Später dann kannst Du diese dann mit "Show()" bzw "ShowDialog()" anzeigen lassen.

Grüße
Norman-Timo

08.10.2009 - 10:29 Uhr

Hallo Tom,

Btw es gibt auch schon fertige FTP Client Klassen im .NET Framework. Siehe FTPWebRequest.

Die Framework FTP Klassen sind aber nur eingeschränkt verwendbar. Versuche mal mit einer offenen FTP Verbindung ein Verzeichnis zu wechseln...

Daher ist die Verwendung einer FTP Library zumindest für mich sehr verständlich.

Hallo dr.hardware,

ich vermute genau wie Tom auch, dass Du keine Schreibrechte auf dem FTP Server hast. Gibt es vielleicht dort ein Verzeichnis "public" oder "upload"? Meist hat man nur auf diesen Verzeichnissen Schreibrechte.

Oder aber Du vebindest Dich anonym mit dem FTP Server und hast dann per se nur Leserechte. Dann versuche Dich mal mit Benutzername und Kennwort zu authentifiezieren, funktioniert es dann?

Ein Fehler 550 ist in der Tat kein Fehler in der Anwendung, sondern eine gültige Fehlermeldung von Seiten des Servers.

Grüße
Norman-Timo

08.10.2009 - 09:41 Uhr

Hallo gordon2001,

hatte Dir ne PM geschickt und Dir Hilfe angeboten !?

Aber unabhängig davon lässt sich Dein Code stark optimieren. Das Arbeiten mit Streams bedeutet eben nicht, dass man bei jedem Verarbeitungsschritt den Stream komplett verarbeiten muss. Im Gegenteil, man übergibt einfach jeder Verarbeitungskette den Stream, und sobald einer daran zieht durchläuft dieser alle Kettenglieder.

Ein Besipiel hierfür (Dateistream <-> GZipStream <-> (De)Serialisierungsstream):


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;

namespace StreamTest
{
    public class Program
    {
        #region main entry point

        static void Main(string[] args)
        {
            TestDataClass deserializedObject = null;
            Program myApp = new Program();
            
            myApp.CreateZipFileFromObject(new TestDataClass(), "TestData.zip");
            deserializedObject = (TestDataClass)myApp.GetObjectFromZipFile("TestData.zip");
            
            Console.WriteLine(String.Format("Testwerte: {0} | {1}", deserializedObject.IntVal, deserializedObject.StrVal));
            Console.WriteLine("Tastendruck beendet das Programm!");
            Console.ReadKey();
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Method which takes an object to serialize it. Than the method will generate
        /// and zip file from the serialization stream.
        /// </summary>
        /// <param name="p_Data">Object to serialize and zip.</param>
        /// <param name="p_zipName">Filename for the zip file.</param>
        public void CreateZipFileFromObject(object p_Data, string p_zipName)
        {
            using (FileStream fs = new FileStream(p_zipName, FileMode.Create))
            {
                using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress))
                {
                    BinaryFormatter binFormatter = new BinaryFormatter();
                    binFormatter.Serialize(zipStream, p_Data);
                }
            }
        }

        /// <summary>
        /// Method which takes the zip filename which is used to decompress and deserialize.
        /// </summary>
        /// <param name="p_zipName">Filename for the zip file.</param>
        /// <returns>Deserialized object.</returns>
        public object GetObjectFromZipFile(string p_zipName)
        {
            object retValue = null;

            using (FileStream fs = new FileStream(p_zipName, FileMode.Open))
            {
                using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Decompress))
                {
                    BinaryFormatter binFormatter = new BinaryFormatter();
                    retValue = binFormatter.Deserialize(zipStream);
                }
            }

            return retValue;
        }

        #endregion

    }
}


Das optimiert in Deinem Falle schon einiges. Verhält sich danach der Speicher besser?

Grüße
Norman-Timo

07.10.2009 - 09:30 Uhr

Hallo gordon2001,

der herkömmliche (De)Serialisierungsprozess für Objekte ist bestimmt nicht 100%ig optimal (nicht falsch verstehen, er ist sehr zu empfehlen, ich vermute aber, dass man hier bei 98% Performanceoptimal liegt und dass nur minimal Verbesserungen möglich sind), aber dass eine 6 MB Datei zum Deserialisieren plötzlich 1,2 GB Speicher benötigt, da muss definitiv etwas ganz schräg laufen.

Ich vermute aber auch sehr stark, dass das nicht am Deserialisierungsprozess aus dem Framework heraus passiert, sondern, dass eventuell die Deserialisierung falsch verwendet bzw. etwas anderes dafür verantwortlich sein muss.

Kannst Du genauer Beschreiben wie Du (De)Serialisierst?

Grüße
Norman-Timo

05.10.2009 - 12:38 Uhr

Hallo zusammen,

ich sehe das genauso wie Tom: Die relevanten ContextInformationen in eine eigene Datnstruktur (Klasse, Struct, oder nur String) kopieren und dem Workerthread und dem Loggen mitgeben.

Genau dafür bietet sich die Logging-Überladung an, die könnte als weiteren Parameter die ContextInformationen erwarten.

Grüße
Norman-Timo

05.10.2009 - 08:58 Uhr

Hallo vollmond,

wenn ich das richtig im Kopf habe will BizTalk den WebService Code haben, damit er diesen bereitstellen kann.

Hast Du schon versucht (testweise), ob Du den WebService auch ohne BizTalk deployen kannst (z.B. über VS und dem IIS)?

Anderer Ansatz ist zu prüfen, ob Du zufälligerweise Assemblies referenzierst, die BizTalk bereits in den Ressourcen aufführt? Versuche mal die Assemblies aus den Referenzen herauszunehmen.

Ansonsten ist eine zirkuläre Abhängigkeit einfach zu erklären:

  • Assembly A referenziert Assembly B und umgekehrt

Grüße
Norman-Timo

02.10.2009 - 16:10 Uhr

Hallo nochmal,

ich bin kein Mod und werde hier nicht darüber entscheiden. Vielleicht gibt hierzu ein Verantwortlicher ein Statement dazu ab?

Grüße
Norman-Timo

02.10.2009 - 15:07 Uhr

Hallo sunnyandy,

hier musst Du auf die manuelle Serialisierung zurückgreifen, denn die automatische nimmt immer die konkrete Klasse, und begnügt sich nicht nur mit der Basisklasse. Wie kann auch ein außenstehender wissen, ob die Kindklasse nicht relevante "Daten" aus der Basisklasse verwendet und verändert.

Die manuelle Serialisierung ist nicht sonderlich schwer, Du musst lediglich das Interface "ISerializable" in der Basisklasse implementieren und einen speziellen "protected" Konstruktor anbieten. Ein sehr gutes Beispiel hierzu findest Du in der MSDN: ISerializable.GetObjectData-Methode

Das direkte Beispiel in der MSDN - ISerializable-Schnittstelle ist wesentlich schwieriger zu verstehen, zeigt aber, dass es auch für komplexe Fälle anwendbar ist.

Viele Grüße
Norman-Timo

02.10.2009 - 14:58 Uhr

Hallo thomas.at,

ich glaube nicht, dass ein Repository in der Sourcecodeverwaltung für Komponententrennung gedacht ist.

Für mich war mein bisheriges Verständnis, dass wenn ich aus einem Repository einen bestimmten Quellcodestand auschecke, dass ich den Quellcode kompilieren kann und dann mein Produkt in der angeforderten Version habe.

Also mal grob erklärt:

  • Ein Repository sind für mich eigenständige Produkte bzw. Solutions
  • Ein Branch ist für mich ein zwischenzeitlich separater Quellcodestrang, der eine definierte Ausgangsbasis hat und ggf. in den Hauptstrang zurückgemergt wird
  • Ein Trunc (den sollte man immer definiert haben) ist der Hauptstrang, in den auch alle Branches zurückfliessen müssen, sofern man die Entwicklung nicht verwerfen will
  • Nur aus dem Trunc werden Release-Versionen gezogen
  • Plugins werden für die Quellcodeverwaltung als benötigter Quellcode angesehen, auch wenn er separat kompiliert werden muss

Ich würde Dein gesamtes Konstrukt (Server_BL, Interfaces etc.) allessamt in ein Repository stecken. Falls parallel Dinge entwickelt werden, dann würde ich einen neuen Branch aufmachen.

Ich hoffe ich habe es verständlich rübergebracht?

Grüße
Norman-Timo

02.10.2009 - 14:48 Uhr

Hallo UliA,

in diesem Forum sind keine Crossposts geduldet, siehe hierzu:
Punkt 2.2 - [Hinweis] Wie poste ich richtig?

Grüße
Norman-Timo

02.10.2009 - 10:42 Uhr

Hallo Peter,

wird xulrunner diese dll laden und nicht mehr in c:\foo\xulrunner nachschauen, ob eine neuere verfügbar ist

Handelt es sich zufälligerweise um eine .NET Dll (Deine bar.dll)? Weil dann könntest Du eine bestimmte Version beim Laden anfordern.

Wenn Du es z.B. in VS per Referenz hinzufügen würdest, dann kann man dort auch "use specific version" einstellen. Das Ganze funktioniert auch bei einem Assembly.Load.

Falls es sich um keine .NET Dll handelt, dann wird mein Vorschlag nicht helfen.

Grüße
Norman-Timo

02.10.2009 - 09:35 Uhr

Hallo joh.w,

für einen Entwicklertest kann man hier die Originalmethode gerne auskommentieren, dann solltest Du alle Stellen sehen, die betroffen wären.

oder ich überlade dann vergesse ich möglicherweise an dieser und jener Stelle was

Das ist bei einer Erweiterung immer der Fall. Zumindest wenn schon vorhandene Stellen die Erweiterung verwenden sollen.

Auch wenn Du es ohne Überladung lösen würdest, kämst Du in die gleiche Problematik etwas vergessen zu können (außer Du sperrst die Originalmethode).

Also Du gewinnst nichts, wenn Du keine Überladung anstrebst.

Grüße
Norman-Timo

01.10.2009 - 15:25 Uhr

Hallo zusammen,

Wegen unterschiedlichen Kategorien könntest du deine bisherige Methode auch überladen und eine default Kategorie nutzen.

So war das gemeint. Wenn keine Kategorie angegeben kommen die Logging Einträge in eine Standard Datei / Datenbanktabelle ...

Schnittstellen sollten generell immer nur erweitert werden, nicht geändert 😃

Grüße
Norman-Timo

01.10.2009 - 09:16 Uhr

Hallo joh.w,

ist es Deine eigene Logger Klasse?

Wenn ja:

Dann erweitere Deine Logging-Klasse, dass man neben dem Logging-Text noch eine "Kategorie" angeben kann. Die Kategorie wird dann dem eigentlichen Loggingtext vorangestellt, oder es wird pro Kategorie eine separate Logging-Datei /-Datenbanktabelle angesprochen.

Dann kannst Du bei den Requests einen eindeutigen Identifizierer (z.B. IP Adresse) verwenden, und Du hast die Möglichkeit die Logging Ergebnisse den Kategorien zuzuordnen.

Vergleiche doch mit dem Ereignislog, bei dem man angeben muss, ob in "System", "Application", "Security" oder in eine eigene Kategorie geloggt wird.

Wenn nein:

Dann sag uns doch welche 😉

Grüße
Timo

30.09.2009 - 19:20 Uhr

Hallo FI/AW,

ich hatte eine ähnliche Anforderung: VB.NET aber noch die alte DAO Technik. Ich habe das so realisiert, dass ich direkt die DAO COM Komponenten ins Projekt eingebunden habe.

Ich gehe jetzt ganz stark davon aus, dass das bei ADO auch so funktioniert. Und ob nun C# oder VB.NET, das ist in diesem Fall kein Unterschied.

Grüße
Norman-Timo

29.09.2009 - 15:48 Uhr

Hallo camelord,

oh, Du hast Recht, den Hinweis habe ich glatt überlesen. Sorry.
Dann muss ich gestehen, dass ich nicht weiter helfen kann. Meine Umstellungen damals haben immer reibungslos geklappt.

Grüße
Norman-Timo

29.09.2009 - 15:26 Uhr

Hallo camelord,

innerhalb der Fehlermeldung ist doch ein Link zu der Microsoft Support Seite angegeben, hast Du Dir dort schon einmal das Tool MetaAcl heruntergeladen und die Berechtigungen angeschaut / angepasst?

Grüße
Norman-Timo

28.09.2009 - 11:01 Uhr

Hallo Herbivore,

ja, Dein Vorschlag wäre dann die Perfektionierung und die Genaueste Implementierung für diese Anforderung.

Grüße
Norman-Timo

25.09.2009 - 14:42 Uhr

Hallo zusammen,

ich würde vermuten, dass so etwas:


if (myMinorDate.AddMonths(6) > myMajorDate)
{
    // Datumsdifferenz ist kleiner als 6 Monate
}

doch völlig ausreichen sollte, oder?

Grüße
Norman-Timo

25.09.2009 - 13:30 Uhr

Hallo VuuRWerK,

ich habe das Problem nicht verstanden, daher bitte ich folgenden Beitrag zu ignorieren, wenn es Dir nicht helfen sollte.

Oracle kann man beibringen, aus welchem Verzeichnis er seine Komponenten lädt. Anhand der Umgebungsvariable ORACLE_HOME wird definiert, wo Oracle sucht.
Siehe auch (zusätzliche Info):
mit c# über das internet auf oracle zugreifen
OracleConnection.Open() wirft Exception

Grüße
Norman-Timo

25.09.2009 - 13:19 Uhr

Hallo jet22,

Falls das nicht geht, könnt ihr mir sagen, wie ich eine bestimmte Eigenschaft einer Klasse als "Standart" definiere

Wenn ich Dich nun richtig verstanden habe, dann ist Vererbung schon genau der Ansatz. Und wenn Du von irgendeiner Klasse erbst und keine einzige Überladung definierst, dann werden alle Methoden und Eigenschaften beim Aufruf dieser über die Basisklasse angesprochen. Das ist der Sinn von Vererbung.

Hey, ich hab das mal eben ausprobiert, weil ich es wissen will, wie das funktioniert, und das ist gar net mal soo trivial.

Also ich bin auf folgende Erkenntnisse gestossen:

  • Das "Item"-Property ist eine Eigenschaft auf sich selbst referenzierend (Indexer)
  • Das kann man nicht mittels "override" überchreiben, da muss ein "new" her
  • Dann ist das Problem, dass Du für das generische Objekt "TValue" keine generelle Instanz mittels "new TValue" erstellen kannst, außer Du definierst hierfür ein Constraint

Alles zusammen ergibt bei mir folgende Umsetzungsmöglichkeit:


    public class MyCustomSortedList<TKey, TValue> : SortedList<TKey, TValue> where TValue : new()
    {
        public new TValue this[TKey key] 
        {
            get
            {
                if (!base.ContainsKey(key))
                {
                    base.Add(key, new TValue());
                }
                return base[key];
            }
            set
            {
                base[key] = value;
            }
        }
    }

Das sollte dem entsprechen, das Du Dir wünschst. Problem wird sein, dass TValue hier einen Default Konstruktor besitzen muss, und dass Du innerhalb dieser MyCustomSortedList keine Ahnung (haben darfst) was für Typen nun neu erzeugt werden.

Prüfe mal, ob das Deinen Anforderung genügt und vor allem versuche zu verstehen, was hier passiert, es hilft Dir nicht, wenn Du das hier blind übernimmst!

Grüße
Norman-Timo

25.09.2009 - 11:44 Uhr

Hallo burkut,

ganz automatisch wirst Du das nicht gelöst bekommen. Du wirst eine programmatische Entscheidung treffen müssen, ob es sich um eine lokale Verbindung handelt oder nicht.

Du kannst aber für die Kommunikation den Channel "dynamisch" gestalten. Irgendwann wirst Du auf den Clients zu dem Punkt kommen, an dem Du den Channel registrieren musst. Hier kannst Du dann den programmatisch ausgewählten Channel verwenden:



// local variables
IChannel myRemotingChannel = null;

// decide channel type
if (IsMyConnectionLocal)
{
   myRemotingChannel = new IcpChannel();
}
else
{
   myRemotingChannel = new HttpChannel();
}

// register Remoting Channel
ChannelServices.RegisterChannel(myRemotingChannel , false);

// get remoting object
// ...


Du kannst so auch per Konfiguration die Verbindungsart wählen. Und Du kannst auch per Switch/Case zwischen den 3 Channel-Types wählen. Das Prinzip sollte mit meinem Codebeispiel klar geworden sein.

Grüße
Norman-Timo

24.09.2009 - 08:54 Uhr

Hallo Bow,

Damit hat sich meine Vermutung bestätigt das es ohne Schleife nicht geht.

auch "atoi" verwendet eine Schleife, das ist technisch auch anders überhaupt nicht möglich.

Grüße
Norman-Timo

Edit: Als offtopic markiert

23.09.2009 - 21:22 Uhr

Hallo zusammen,

Du kannst mittels Webbrowsercontrol jede auch im Internet verfügbare Werbequelle einbinden.

Vorausgesetzt, dass das Programm auch Internet- verfügung/berechtigung hat.

Ansonsten kannst Du ja ein paar Firmen gezielt anschreiben und Fragen, ob diese Grafiken zur Verfügung stellen, die Du dann selbst auf der Form einbindest. Gegen eine kostenlose Werbung wird kaum eine Firma was dagegen haben 😉

Grüße
Norman-Timo

23.09.2009 - 21:18 Uhr

Hallo codeGenerator,

manchmal besitze ich doch eine Glaskugel 😉) Oder: ich hab schon zu viel gesehen im Leben 😁 Oder nochmal anders ausgedrückt, ich hab in meinem Softwareleben schon sehr viele Probleme beheben müssen... Genug Eigenlob, (das brauch ich grad, damit ich mich besser fühle 😉

Schön aber, dass Du Dein Problem (fast) ohne meine Hilfe lösen konntest.

Grüße
Norman-Timo

23.09.2009 - 14:10 Uhr

Hallo codeGenerator,

dass Programm erkennt, wenn Assemblys aktualisiert wurden.

Ok, das lässt sich in der Tat nicht mit der ApplicationContext abbilden.

Also dann: Back to the error:
Eventuell wird die Assembly nicht richtig entladen, Du könntest das Testprojekt von vorhin noch einmal laufen lassen aber dieses Mal aus VS per Debugging heraus. Falls es ein "Entladungsfehler" sein sollte, und das Problem darin bestehen, dass der GC nicht alles sauber aufräumen kann, dann würde sich Deine Debugging Session nicht mehr beenden lassen, obwohl alle Fenster zu sind.

Wenn die Änderung des SplashScreen die Fehlerursache sein sollte, dann sollte man dort mal nach Resourcen/Events/Delegates suchen, die nicht sauber aufgeräumt werden.

Testweise kann man auch ein "Application.Exit()" auch innerhalb der AppDomain ausführen lassen, dann sollte sicherlich alles aufgeräumt werden (ist aber nur für Testzwecke sinnvoll, nicht als Lösungsvorschlag zu verstehen).

Ich habe selbst einmal Probleme damit gehabt, mit einem selbstgestrickten SplashScreen und dem "Application.Run()", so dass sich die Applikation nicht sauber beendet hatte. Da würde ich am ehesten die Problemursache sehen.

Kannst Du eine kleine Beispieldemo bauen (Code) und hier bereitstellen, die das Konstrukt mit der Main-Methode, der AppDomains und vielleicht 2 Dummy-AppDomain-Assemblies mit Dummy-Forms und/oder SplashScreen abbilden.

Dann könnte ich versuchen Dir konkret zu helfen.

Grüße
Norman-Timo

23.09.2009 - 13:17 Uhr

Hallo OldSchool,

Also das man sich die Definition der DataTable mit den Columns erspart und einfach die Query mit dem SqlCommand abfeuert und dann aus dem ResultSet eine DataTable erzeugt?

Nicht ganz 😉

Eventuell ist der SqlDataAdapter hier etwas für Dich. Damit kannst Du Deine DataTable direkt mit Struktur aus der Datenbank ziehen.

Beispiele:
MS SQL DataAdapter - SQLCommand -> unterschied?
MSDN - SqlDataAdapter Klasse
und viele Anwendungsbeispiele hier im Forum mit dem Suchbegriff "SqlDataAdapter"

Grüße
Norman-Timo

23.09.2009 - 13:08 Uhr

Hallo codeGenerator,

ich denke Du kannst Dir den ganzen Kram mit der AppDomain sparen. Ich denke, Du kannst hier die ganze Anforderung mittels dem ApplicationContext lösen. Siehe z.B. hier: MSDN - ApplicationContext Klasse

Der Context wird dann so gestaltet, dass dort eine Schleife um "MySplashScreen.ShowDialog()" und "MyMainWindow.Show()" gestrickt wird, die als Bedingung enthält, dass das "Programm" neu gestartet wird.

Versuche erst einmal zu Verstehen, wie das mit der ApplicationContext funktioniert, solltest Du dann noch Schwierigkeiten in der Umsetzung haben, dann werde ich Dir gerne weiterhelfen.

Grüße
Norman-Timo

23.09.2009 - 11:20 Uhr

Hallo codeGenerator,

kannst Du mal folgenden Test ausführen:

  • Erstelle ein neues Win-form Projekt
  • Füge die Referenz Deiner Assembly hinzu (die Du in einer AppDomain ausführst)
  • Ändere in der Main-Methode das Startfenster auf das Login-fenster aus der Assembly um

Dann kompiliere das und führe die generierte EXE aus. Tritt dann immer noch eine "AccessViolation" Ausnahme auf?

Hintergrund: Nach diesem Test kannst Du den Fehler genauer lokalisieren. Ist es ein reiner Fehler in der Assembly (dann müsste beim Test der Fehler erscheinen), oder hat es was damit zu tun, dass Du Querzugriffe zwischen den 2 AppDomains hast (dann darf der Fehler im Test nicht auftreten).

Ich vermute mal stark 2. Szenario.

Grüße
Norman-Timo

23.09.2009 - 08:26 Uhr

Hallo svenson,

Aber vielleicht geht demnächst wieder alles durch den Browser mit HTML5 und Websockets... 😉

😁 👍

Grüße
Norman-Timo

22.09.2009 - 18:40 Uhr

Hallo meisteralex,

naja, als ungelöst würde ich es in dem Artikel nicht sehen. Der Autor sagt, dass seine "dynamic Factory" keinen Registrierungsweg vorgibt, und dass es dem Verwender freigestellt ist, wie er seine zu registrierenden Typen findet.

Er sagt, dass es z.B. möglich ist über eine Datenbank zu gehen, oder über PlugIn Verfahren, oder wie hier bereits erwähnt kann man Reflection hierfür verwenden.

While the Factory<TKey, TBaseType> class works pretty well, you still need some code to get it working. This is because you always have to check whether the factory returns null and if so, you'll have to add a new type to the factory. The way you want to create new types for the dictionary is totally domain specific. Maybe you have a plug-in based system with assemblies referenced from a configuration file, or you could define the type names in the database and add new assemblies to the bin folder of your web app.

@winSharp93:
Ich persönlich bevorzuge lieber die Variante per Reflection Assemblies aus einem Verzeichnis zu analysieren und nach bestimmten Interfaces oder Attributes Ausschau zu halten. Aber das ist Geschmackssache, hier kann man definitiv nicht sagen, das eine oder das andere wäre "besser".

Viele Grüße
Norman-Timo

22.09.2009 - 16:33 Uhr

Hallo zusammen,

ein anderer Ansatz ist die Prozesspriorität auf "Niedrig", oder "Niedrigst" (ich kenn jetzt nicht auswendig die korrekte Bezeichnung, sorry) zu stellen, dann ist gewährleistet, dass (fast) alle anderen Prozesse bevorzugt werden.

Grüße
Norman-Timo

22.09.2009 - 16:20 Uhr

Hallo zusammen,

bevor jetzt alle auf Jéré rumhacken. Es gibt hier Issues (von mir in .NET 2.0 validiert, in WCF noch nicht), die sehr stark an der Zuverlässigkeit von MouseUp Events und auch MouseLeave Events zweifeln lassen.

Ich habe für mich entschieden, einen Win-Api Mousehook dafür zu implementieren, denn das funktionierte sehr viel zuverlässiger.

Siehe z.B. auch MSDN - WM_LBUTTONUP

Warum das so ist kann ich nicht erklären, aber im Web findet man sehr viele gleichartige Problembeschreibungen hierzu. Das ist auch meines Erachtens kein Implementierungsfehler.

Grüße
Norman-Timo