Laden...

Forenbeiträge von Traumzauberbaum Ingesamt 512 Beiträge

29.07.2006 - 18:06 Uhr

Das ist eben nur ein Wert der dir anzeigt, ob du gerade in DesignTime bist.

Z.B. wenn man ein Component schreibt, dass sich mit einem anderen PC verbinden soll. Es wär ja irgendwie blöd, wenn man die ganze Zeit während man mit dem Designer arbeitet ständig Fehler kriegt, dass die Verbindung nicht aufgebaut werden konnte.
Also steckt man den ganzen Aufbau kram hinter ein if( !DesignTime ) und es wird eben nicht zur Entwurfszeit ausgeführt.

29.07.2006 - 17:57 Uhr

Im Prinzip ist der gute alte Stackoverflow ja nichts anderes als selbstmodifizierender Code 😁

28.07.2006 - 19:13 Uhr

Also nach dem Satz von Rice würde ich mal eiskalt behaupten das Programm könnte eh nicht völlig korrekt entscheiden.

26.07.2006 - 18:37 Uhr

Da Worte wohl nicht helfen...

Probier mal das angehängte Programm aus.

Mit F1 und F2 teilt man den Threads Rechenzeit zu.

F1 - F1 - F2 - F2, danach beliebig fortsetzen
Dann solltest du sehen wo der Fehler liegt.

Oder du sagst mir was ich da falsch implementiert habe.

26.07.2006 - 15:55 Uhr

Original von Bernhard

Original von Traumzauberbaum
Der Manager soll doch aber auch synchronisiert sein.
Wenn du dir da den Decorator nicht dafür gedacht hast, muss man es anders machen. [...]

Wie gesagt, darum muss sich der Manager selbst auf "klassische" Weise kümmern.

Und genau dadurch kommt es zu Deadlocks. Weiß auch nicht wie ich dir das noch erklären soll. Der Code den du gepostet hast erzeugt keine Deadlocks. Aber wenn man es mit den anderen Synchronisationsanforderungen kombiniert steht man genauso schlau da wie vorher.

  1. Es wird eine Funktion vom Manager aufgerufen. Der greift dazu auf ein Objekt zu.
  2. Kurz vor dem zugriff wird auf dem Objekt ein Event ausgelöst. Dadurch bleibt der Manager am lock kleben.
  3. Bei der Abarbeitung des Events muss das Objekt auf den Manager zugreifen und eine Funktion davon abrufen.

Folge:
A) Es laufen zwei Funktionen beim Manager nebeneinander, weil das nicht durch ein lock verhindert wurde
ODER
B) Das ausgelöste Event kann seine Funktion nicht fortsetzen, weil das nebeneinander ausführen von Funktionen vom Manager durch ein lock verhindert wird. Der Manager kann aber auch nicht fortsetzen, weil das Objekt noch das Event abarbeitet => Deadlock

Es ist aber beides nicht erwünscht.

26.07.2006 - 15:30 Uhr

Das glaub ich dir nicht, weil es schlicht unmöglich ist.
Kopier dir den Code mal ins Programm.

Es kann lediglich passieren, dass die Reihenfolge der Ausgabe unterschiedlich ist.
Das was du aber behauptest kann einfach garnicht passieren. Es ist unmöglich, weil die Variable string _name eine lokale Variable der Funktion WriteName ist.

Ich hab den Code mal geändert um das was du behauptest mal wirklich zu provozieren:

public class Programm
{
    public static string _name = "name1";
    public static object _lockObject = new object();
    public static void Write(string name)
    {
        // lock eigentlich unnötig, wird auf nichts was außen liegt und sich ändert zugegriffen
        Thread.Sleep(1000);
        Console.WriteLine(name);
    }
    
    public static void WriteName( object name )
    {
    	//string _name = name.ToString();
        Console.WriteLine("Nutze " + _name);
        
        Thread.Sleep( 1000 );
        Write(_name);
    }
    
    static void Main(string[] args)
    {
        ParameterizedThreadStart start = WriteName;
        Thread t = new Thread(start);
        t.Start( _name );
        Thread.Sleep(100);
        _name = "name2";
        WriteName( _name );
        t.Join();
        Console.ReadLine();
    }
}

Das provoziert wirklich immer den Fehler. es wird erst "Nutze name1" geschrieben und dann gewartet. Währenddessen ändert sich die statische Variable _name. Erst dann geht es in der Funktion weiter.

Jetzt entferne die "//" bei "//string _name = name.ToString();" und es ist schlicht unmöglich, dass du das gleiche Verhalten beobachtest.

26.07.2006 - 15:15 Uhr

Der Manager soll doch aber auch synchronisiert sein.
Wenn du dir da den Decorator nicht dafür gedacht hast, muss man es anders machen. Aber gemacht werden muss es. Schließlich sollen auch solche Fälle synchronisiert werden:

  • Event löst in Decorator A für Objekt A Methode A aus: Objekt A greift auf Methode A vom Decorator A für Manager A zu
  • Manager A macht irgendwas

Das darf natürlich auch nicht gleichzeitig laufen, sondern soll synchronisiert sein.
Und dann kommt man wieder zu einem Deadlock wenn folgendes passiert:

  • Event löst in Decorator A für Objekt A Methode A aus: Objekt A greift auf Methode A vom Decorator B für Manager A zu
  • Manager A ruft für Decorator A für Objekt A Methode B auf

Manager A ist gerade beschäftigt, parallel darf er nichts anderes machen. Der Decorator A blockiert aber das, was der Manager machen will. Parallel dazu versucht der Decorator B auf dem Manager was ausführen zu lassen. Der lässt das aber nicht zu, weil eben immer nur eine Funktion gleichzeitig laufen darf.

26.07.2006 - 13:23 Uhr

Überleg dir das analog für den Manager.

Auch bei dem müsste man also immer über den Decorator zugreifen.

=> Deadlocks

26.07.2006 - 13:01 Uhr

Nein ich meinte wenn die Funktionen nicht auf den Manager zugreifen.

Folgendes Beispiel soll ja auch synchronisiert werden:

Event löst in Objekt A Methode A aus
Manager greift auf Objekt A Methode B zu

Genau da kannst du es nicht vermeiden, dass sich die Objekte auch selbst um synchronisation kümmern, das ist Teil der Anforderung.
Wenn du sowas einfach zulassen kannst, gibts keinen Grund das Objekt überhaupt irgendwie zu synchronisieren. Dann macht man locks nur beim Manager und lässt den Rest halt laufen, und hat das Problem auch nicht.

So oder so, deine Lösung ist unwirksam. Entweder man braucht sie nicht, weil die Objekte nicht synchronisiert werden müssen. Oder sie führt genauso zu Deadlocks.

26.07.2006 - 12:03 Uhr

Das Problem ist doch, dass dein Code unwirksam ist, er behebt keine Deadlocks.

Oder du lässt dabei völlig außer acht, dass die Objekte auch synchronisiert sein sollen, wenn sie nicht mit dem Manager arbeiten.

Hängt davon ab wie du die Objekte nach außen hin zeigst, aber eines von beiden trifft auf jeden Fall zu.

Modifizierst du eben das, kommst du zu einem gemeinsamen Lock.

26.07.2006 - 11:23 Uhr

Am Ende ist das 2. auch nur eine umständliche Variante bei der auf ein gemeinsames Objekt gelockt wird.

25.07.2006 - 23:56 Uhr

Was du suchst sind Arrays

25.07.2006 - 23:09 Uhr

Das kannst du prinzipiell nie sicherstellen. Jeder Depp kann ja über Reflection auf jedes beliebige Objekt zugreifen wenn er will. Ich meine wenn jemand mit an der Assembly arbeitet und er will an das lockObject, macht er es halt public und gut ist.

Die Frage ist doch viel eher: wie kriegst du es umständlich genug, dass es nicht ausversehen passiert. Und dabei schwingt implizit mit: was traust du den Leuten die an der Assembly mit arbeiten zu 😉
Könntest z.B. irgendwo zentral (bzw. im Manager) dieses Objekt über eine GUID identifizieren. Da wird man dan schon absichtlich die gleiche nehmen müssen.

Die einzige alternative die mir einfällt wäre, einen der Aufrufe so weit zurückzurollen, bis der andere freie Hand hat. Z.B. könnte man eine Exception den Stack runter laufen lassen. Nur wirds wohl recht kompliziert rauszufinden, wo die Exception dann letztendlich gefangen werden soll, also wo die Ursache des Deadlocks liegt. Und da steht ja immernoch die Frage im Raum: kann ich überhaupt so weit zurückgehen ohne irgendwo wieder was einzureißen?

25.07.2006 - 20:35 Uhr

Naja man sollte das auch mit jedem anderen beliebigen Datenbanktool hinkriegen können. Z.B. auch mit dem Server Explorer von Visual Studio sollte das auch gehen.

25.07.2006 - 14:20 Uhr

Dein Problem ist, dass du nicht die geringste Ahnung hast was da passiert und es auch nicht rausfinden willst. Von den 23000 Zeilen Code ist über die Hälfte einfach nur dazu da, damit du weiter im Designer rumklicken kannst um z.B. DataBindings damit zu setzen. Eine überaus anspruchsvolle Aufgabe die 1 Zeile Code beansprucht. Von dem Rest sind locker 90% für den typisierten Zugriff auf die Spalten.

Eine Anwendung die eine DataTable aus der Datenbank in einem DataGridView anzeigt, braucht für den Zugriff auf die Datenbank kaum 15 Zeilen Code wenn man das per Hand macht. Und dann kommt pro DataBinding eine Zeile Code dazu...

Und nochmal abschließend: Mit den ? ist alles korrekt, der Fehler liegt nicht dort.

25.07.2006 - 13:57 Uhr

Ok mit Designern hab ich noch wenig zu tun gehabt. Ist eben der Vorteil wenn man sowas per Hand schreibt: Man weiß was da los ist.

Also wenn der Debugger nicht gerade auf der Datenbank läuft und du die eingehenden Befehle siehst, würde ich mal sagen du täuschst dich. Der CommandText des DbCommands ändert sich nie, auch nicht bei der Ausführung. Ich bezweifle ernsthaft, dass du das irgendwie in deinem Code beobachten kannst, an welcher Stelle das dann passiert.

25.07.2006 - 13:19 Uhr

Gibt noch einen 😁

Nicht so viel Aufwand. Dafür muss man diesen bei jedem neucompilieren wieder machen:
http://www.c-sharpcorner.com/Code/2003/Aug/ExportManagedCodeasUnmanaged.asp

Musst im Prinzip die DLL erstmal in IL Code umwandeln (ildasm.exe)
Und dann in dem Code ein paar Zeilen editieren.
Brauchst dir nicht unbedingt den ganzen Text antun, relativ weit hinten steht dann der komplette IL-Code dieses Beispiels mit ausreichend markierten Änderungen und Kommentaren.

Hab das Verfahren getestet und es funktioniert! 😁
Ich weiß allerdings nicht wie das mit Parametern funktioniert. In meinem Fall hatte ich relativ triviale int Parameter, und einen IntPtr (HANDLE in C++ Code), da hatte es ohne Probleme funktioniert. Keine Ahnung ob das Marshallen genauso funktioniert wie bei "C++ dlls in C# verwenden".

Wär mal toll wenn jemand dazu vieleicht ein automatisches Tool schreiben könnte.
Das größte Problem dabei ist die Stellen zum einfügen zu finden, dafür muss man wohl etwas den IL Code parsen können

25.07.2006 - 12:45 Uhr

Ja das Problem kenne ich auch.

Beispielsweise sollte ein Programm Daten aus einer Tabelle nehmen und zusammen mit ein paar zusätzlichen Informationen in eine andere Tabelle schreiben.

Witzigerweise sind aber die Definitionen der Spalten völlig willkürlich. So ist auf der einen Seite ein Feld mal als char definiert, auf der anderen als decimal. Und manchmal steht dann auch was in dem Feld drinnen, was eben keine Nummer ist. Dann ist ein Feld auf der einen Seite als char(12) definiert, auf der anderen als varchar(10) und ratet mal von welchem in welches geschrieben werden soll 😉
Wenn man dann bei 117 Spalten bei der Hälfte ein try/catch hat, die aber nur zur Fehlerbehandlung sind, nicht wirklich echte Exceptions die die Ausführung beenden sollen, wirds irgendwann doch unleserlich.

Bei Problemen die man häufiger hat, lohnt es sich kleine Helferfunktionen zu schreiben, in der Tradition von int.TryParse.
try/finally Blöcke kann man oft durch ein using zumindest etwas übersichtlicher gestalten.
Und lange Funktionen in kleinere Funktionen unterteilen, zur besseren Überschaubarkeit.

Anders lässt sich manches einfach nicht lösen, gerade bei manchen DB Sachen hat man es versäumt eine Fehlerbehandlung ohne Exceptions auch nur ansatzweise zu ermöglichen.

25.07.2006 - 12:12 Uhr

Du benutzt den System.Net.Odbc Provider und bei diesem werden Parameter mit ? markert. Die Parameter werden dann erst beim Ausführen der Commands eingesetzt. Es ist da also alles in Ordnung.

Muss man nicht erst einen DbCommandBuilder (OdbcCommandBuilder) mit dem Adapter verbinden, damit das Update automatisch funktioniert?

25.07.2006 - 12:07 Uhr

Nur als ungetestete Vermutung:
Vieleicht bekommt man das auch über COM mit der oledb32.dll hin...

25.07.2006 - 11:31 Uhr

Klingt für mich nach ner netten Abwechslung. Ich entwickle sonst ja eher Anwendungen, bisher noch keine Spiele.

Ich würde da schon gerne Mitmachen.

25.07.2006 - 10:17 Uhr

Ich bin echt froh, dass es so ein Ende nimmt, und nicht noch weiter eskaliert.

24.07.2006 - 23:03 Uhr

Also erstmal hatte ich ziemliche Probleme rauszufinden was bei dir überhaupt schiefläuft.

Erstmal um das vieleicht klarzustellen (kannst es ja verneinen wenn ich was falsch verstanden habe):
Das Problem ist nicht, dass sie die Parameter des Funktionsaufrufs ändern. Ich hatte schon ziemlich gestaunt als ich das gelesen hab, das halt ich irgendwie für ziemlich unmöglich. Bzw. muss man da schon sehr viele bösartige Bemühungen reininvestieren um das zu schaffen.
Es ändert sich einfach eine Membervariable, auf die die Funktion zugreift. Der Unterschied ist imo ziemlich enorm.

Das Problem lässt sich nämlich genau damit lösen: Parameter.
Zumindest bei Wertetypen (und string) funktioniert das, weil dann eine Kopie auf dem Stack liegt, und mit dieser gearbeitet wird. Wenn die Variable geändert wird, merkt man das also nicht.
Für Referenztypen (class) muss man für das gleiche Verhalten selbst eine Kopie anlegen und diese als Parameter übergeben. So, dass an der Kopie dann eben keine Änderungen von Außen mehr gemacht werden können.

Für .NET 2.0 lässt sich das ganz leicht machen. Hier dein modifiziertes Beispiel:

public class Programm
{
	public static string _name = "name1";
	public static object _lockObject = new object();
	public static void Write(string name)
	{
		// lock eigentlich unnötig, wird auf nichts was außen liegt und sich ändert zugegriffen
		Thread.Sleep(1000);
		Console.WriteLine(name);
	}
	
	public static void WriteName( object name )
	{
		string _name = name.ToString();
		Console.WriteLine("Nutze " + _name);
		Write(_name);
	}
	
	static void Main(string[] args)
	{
		ParameterizedThreadStart start = WriteName;
		Thread t = new Thread(start);
		t.Start( _name );
		Thread.Sleep(1);
		_name = "name2";
		WriteName( _name );
		t.Join();
		Console.ReadLine();
	}
}

Für .NET 1.1 wirds etwas komplizierter, da musst du selbst eine Übergabe an einen Thread nachbilden. Z.B. indem man ne Klasse schreibt, die den Parameter hält und eine Funktion als ThreadStart zur Verfügung stellt, die dann selbst wieder ne andere Funktion mit eben dem gehaltenen Parameter aufruft. Naja mit bissel Fantasie versteht man vieleicht was ich meine 😉

24.07.2006 - 21:03 Uhr

Naja erstmal kann man keine Klassen an das PropertyGrid übergeben, sondern nur Objekte. Ich schlag vor du machst dir den Unterschied nochmal klar, sonst könnte es auch später nur verwirrend und kompliziert werden.

Das Zweite:
Das PropertyGrid benutzt zum auslesen der Properties einen PropertyDescriptor. Wenn man für eine Klasse keinen PropertyDescriptor über ein Attribut angegeben hat, wird der Standard hergenommen. Und der ließt eben aus der Klasse des übergebenen Objekts die Properties aus, und zeigt diese an.
Um jetzt also dynamisch zur Laufzeit für eine Klasse unterschiedliche Properties anzuzeigen, müsstest du einen eigenen PropertyDescriptor schreiben. Das ist imo auch nicht gerade wenig zu tun, so ganz hab ich da auch noch nicht durchgeblickt.
Sowas macht z.B. OdbcConnectionStringBuilder. Wenn du im ConnectionString z.B. "Irgendwas=Wasweißich" angibst, erscheint dann unter den Properties plötzlich eine mit Namen "Irgendwas" und Wert "Wasweißich". Oder wenn du dort "BrowsableConnectionString" auf false setzt, taucht erst garnicht die Property ConnectionString in der Liste auf.

24.07.2006 - 20:33 Uhr

Original von norman_timo
vielleicht bin ich etwas zu stark Informatiker? Aber für mich spielen solche Detailfragen keine Rolle.

Das gleiche trifft wohl auf mich zu 😁

Ich hätte das wohl nichtmal gemerkt, wenn es dazu keinen Thread gäbe. Bzw. hätte ich dann ein halbes Jahr später gefragt, ob das denn schon immer so aussah 😁

24.07.2006 - 20:14 Uhr

Naja ganz so stimmts nicht.

Also ich hab im Hauptprogramm keine invarianten Resourcen definiert. Das heißt die stehen nur in der DLL. Von dort kann ich die auch wunderbar laden. Also ich kann aus einer DLL leicht die invarianten Resourcen holen, aber ich kriegs nicht hin das gleiche mit den anderen Cultures zu machen.

Hier hab ich vieleicht eine Lösung. In der zweiten Hälfte geht es genau um das Thema. Aber da werden wohl keine Assemblies benutzt, sondern blanke .resource Dateien. Die werden dann in ein bestimmtes Verzeichnis gelegt und der FileBasedResourceManager sucht dann in diesem Verzeichnis nach den Resourcen.

Im Prinzip könnte man das aber auch genauso mit dlls machen. Die Dlls müssten dann eben auch so aufgebaut sein:

  1. Eine DLL enthält nur eine Culture
  2. Die DLL ist nach der enthaltenen Culture benannt

Dann würde man diese enthaltene Culture für diese DLL eben als InvariantCulture definieren, die kann man ja scheinbar problemlos laden. Wenn man auf eine bestimmte Culture zugreifen will, muss man die DLL suchen, die nach dieser benannt ist, und von dort die invarianten Resourcen laden.

24.07.2006 - 18:44 Uhr

Also ich habs vorhin getestet. Ein kleines Konsolenprogramm und eine DLL mit ner .resx drin, die einen String enthält.

Die DLL hab ich dann über LoadFile geladen, und eben den ResourceManager erstellt.

Und mit GetString hab ich dann genau das erwartete Ergebnis erhalten. Er wird sich den Inhalt von dem String ja nicht zufällig richtig ausdenken.

Nur mit GetString mit CultureInfo hab ich etwas Probleme, da werd ich wohl noch was falsch machen. Der String für die InvariantCulture hat funtioniert.

24.07.2006 - 18:00 Uhr

Original von dutop

ResourceManager rm = new ResourceManager("... .Strings", System.Reflection.Assembly.LoadFile(@"C:\...\en\....resources.dll"))  

Bei mir funktioniert das genau so.

Ruf doch mal resAssembly.GetManifestResourceNames() auf und schau was für Namen überhaupt drin sind.

24.07.2006 - 13:13 Uhr

Also Prinzipiell wenn man einen Thread erstellt und den auf IsBackground = true setzt, beendet er sich wenn der letzte Thread mit IsBackground = false sich beendet. Also z.B. wenn man nur den Hauptthread und einen Backgroundthread hat, dann wenn das Programm beendet.

Speziell der FileSystemWatcher läuft doch aber sowieso schon in einem eigenen Thread. D.h. du musst nur den FileSystemWatcher erstellen und aktivieren (Filter nicht vergessen) und musst nicht selbst extra noch nen Thread erstellen. Selbst wenn du den beim Programmende nicht selbst wieder abschaltest, müsste er das eigentlich alleine hinkriegen.

24.07.2006 - 13:00 Uhr

Original von dutop
2. Ich bezweifle, dass man da reinspringen wird. Er findet ja die DLLs nicht, also kann er auch keine Fehler feststellen

Doch er kann den Fehler "Kann DLL nicht finden" feststellen 😉
Wenn er die DLL nicht finden kann, sollte er eigentlich das AssemblyResolve Event auslösen.

Aber warum er die Resourcen nicht laden kann weiß ich jetzt auch nicht. Davon hab ich keine Ahnung. Auf jeden Fall scheint mir das aber ein anderes Problem zu sein, die Assembly scheints ja erfolgreich geladen zu haben, sonst käme ja eine entsprechende Exception.

Wenn man die Assembly erstmal geladen hat, sollte es auch keinen Unterschied mehr machen woher die geladen wurde, ob GAC, Hauptverzeichnis, temporäre Assembly oder was auch immer.

Aber joh.w ich weiß nicht so recht was du für eine Lösung erwartest. Soll das Programm erraten wo sich die anderen DLLs befinden?
Und ich hab immernoch das Gefühl, dass ich auf dem Holzweg bin 😉

24.07.2006 - 11:25 Uhr

Ja kann man.

Allerdings verwendet Enum einen bestimmten TypeConverter, der eben für das Enum alle Werte ausliest. Den Job müsstest du übernehmen.

Das heißt du musst eine von TypeConverter abgeleitete Klasse erstellen. Bei dieser Klasse musst du dann folgende Methoden überschreiben:

GetStandardValuesSupported
GetStandardValuesExclusive
GetStandardValues

Eigentlich selbsterklärend was die machen. Damit lieferst du eben die Elemente der DropDown Liste und definierst, ob man auch eigene Eingaben machen kann.

Dann musst du aber noch die ConvertTo, CanConvertTo, ConvertFrom, CanConvertFrom überschreiben. In denen machst du dann aus einem Wert den Text, der angezeigt werden soll, und andersrum.

Ist eigentlich alles halb so schwer wie es vieleicht klingt. Und auch nicht sonderlich umfangreich.

24.07.2006 - 10:28 Uhr

Man kann doch:

  1. In der AppDomain festlegen in welchem Verzeichnis nach Assemblies gesucht wird (z.B. AppDomain.AppendPrivatePath)
  2. AppDomain.AssemblyResolve oder AppDomain.ResourceResolve benutzen um Fehler beim Laden der Assemblies selbst zu beheben.
  3. Manuell schon die Assemblies laden, sodass sie garnicht erst gesucht werden müssen (Assembly.Load)

Vieleicht verstehe ich auch nur das Problem falsch.

23.07.2006 - 21:38 Uhr

Wenn überall Werbung in der Art wäre, wär das Internet ein Stück erträglicher 😉

23.07.2006 - 15:03 Uhr

Original von Golo Haas
Der Punkt ist, dass es zu 1) Aussagen von mir gab, auf die man sich beziehen kann.

Zu 2) wurden Vermutungen und Unterstellungen geäußert, die eben jeglicher Grundlage entbehren (es wurde ja nicht gefragt, hey, gibt's da eventuell Zusammenhänge, sondern es wurde einfach mal davon ausgegangen, dass dem so ist).

Das ist der Unterschied.

Jetzt erklär mir aber mal wie du das als so beleidigend auffassen kannst, wenn du aber doch der Meinung bist, dass es dein gutes Recht ist genau das zu tun.

23.07.2006 - 14:57 Uhr

Überleg doch selbst mal wie das ganze aussieht.

  1. Bei der Diskussion über die Links (an der ich mich nicht beteiligt habe), stellst du ganz klar, dass du es als dein Recht ansiehst aus der Seite auch Vorteile zu ziehen. Vorteile finanzieller Natur durch neue Kunden.

  2. Stellt man dann Vermutungen zu irgendwelchen Verbindungen zu Basta oder was auch immer an, aus denen du ja auch nicht mehr als finanzielle Vorteile hättest, siehst du das als persönlichen Angriff an.

Wie kann man gleichzeitig beide Meinungen vertreten? Bei 2. hast du doch eindeutig selbst gemerkt, dass sowas absolut kein normaler Zustand ist, während du das bei 1. aber noch voll vertrittst.

23.07.2006 - 14:47 Uhr

Achso also ging es nicht um die Links, die du zur Kundenwerbung benutzt hast und jetzt entfernt hast, weil du die Diskussion und ungerechtfertigten Unterstellungen leid bist?

PS Und ungerechtfertigt sind diese Vorwürfe auch nicht. Sie sind vieleicht völlig falsch, aber gerechtfertigt werden solche Vermutungen durch deine eigenen Kommentare.

23.07.2006 - 14:40 Uhr

Original von Golo Haas
Das sind alles Vermutungen und Annahmen, aber keine Fakten. Hier wird größtenteils auf der Basis von Halb- oder Nichtwissen argumentiert. Und das - ganz offen gesagt - nervt. Wer etwas behauptet, sollte es auch belegen können, und nicht einfach mal irgendeine Behauptung in den Raum stellen.

Jetzt tu mal nicht so mimosenhaft. Du hast selbst oft genug betont, dass es dein gutes Recht ist auch nen Vorteil aus der Sache zu ziehen. Diese Seite zur Kundenwerbung zu benutzen, noch mehr, du hast sogar gesagt, dass es funktioniert. Tu nicht so als hätte man sich das alles ausgedacht.

23.07.2006 - 10:37 Uhr

Original von S.H.-Teichhof
du sagst der einzelne soll keinen Profit aus der leitung der Community Ziehen?
aber was macht ein Fragensteller wenn er eine frage stellt und die Antwort nutzt?
ist das Kein Profit?

Zwischen Profit in Euro und Profit in Erkentniss ist es eben ein Unterschied. Das eine ist der Sinn der Community. Ich meine wenn ich sage "ich brauch mal etwas Geld", würdest du mir da helfen? Im Gegensatz zu "ich brauch mal etwas Hilfe".

Mich persönlich stören die Links wie gesagt nicht, aber im Lauf der Diskussion hat sich bei mir eben auch die Frage aufgeworfen wohin der Weg führt. Solange es nur bei den Links bleibt, hab ich kein Problem damit.

22.07.2006 - 23:27 Uhr

Erstell einfach mal mit nem Designer ein Label und schau dir den Code an.

Gerade mit .NET ist wirklich nichts leichter als das.

22.07.2006 - 22:10 Uhr

Original von purplestar
Wenn man schon vor einen Karren gespannt wird (auch als noch so kleiner Teil einer Community) dann möchte man vielleicht vorher gefragt werden ob das ok ist.

Das trifft so ziemlich genau meine Gefühle zu dem Thema. Ich finde nicht, dass ein einzelner Profit aus den Leistungen der Community ziehen sollte.

Die Links an sich find ich ja nichtmal schlimm, deswegen hab ich mich hier auch nicht weiter geäußert. Aber mich erschrecken ehrlich gesagt etwas Golos Kommentare zu dem Thema.

22.07.2006 - 14:11 Uhr

Warum gibst du uns dann nicht einfach alle Informationen die du hast?

Eine Fehlermeldung verweist immer auf eine bestimmte Zeile.
Und ich bin mir sogar ziemlich sicher, dass diese Zeile nicht bei dem enthalten ist was du gepostet hast.

Aber was mir auffällt, das Serializable Attribut braucht man doch nur bei MarshalByValue. Sollte aber eigentlich eher nicht zu nem Fehler führen.

22.07.2006 - 14:05 Uhr

Das ist eigentlich wieder ne typische Fehlermeldung in der alles steht was du wissen musst.

Schau dir doch mal an wie MethodInvoker definiert ist.

Du musst auch keinen MethodInvoker an Invoke übergeben, sondern irgendeinen beliebigen Delegate-Typ

21.07.2006 - 18:02 Uhr

Na das mit dem Scripter hat sich bei UO so eingebürgert.

Sphere war eben eines der beliebtesten Server Emulationen. Dort waren/sind nur Scripts möglich. Genauso war damals RunUO, der C# Server Emulator, noch nicht Open Source und somit dort ebenfalls nur Erweiterungen in Form von Scripts möglich.

In dem Sinne dreht es sich wohl wirklich Größtenteils um Scripts.

21.07.2006 - 16:59 Uhr

Du brauchst in der Klasse eine Property, die diesen Wert zurückliefert.

Dann gibst du für die ComboBox als ValueMember eben den Namen der Property an.

Funktioniert übrigens auch für das was er anzeigt, musst nicht unbedingt ToString überschreiben. Es reichte eine Property, die die Zeichenkette zurückliefert. Und deren Namen gibst du dann als DisplayMember an.

Achja einen Haken hat die Sache noch. Jedesmal wenn man die DataSource Property der ComboBox ändert, muss man auch diese beiden Properties DisplayMember und ValueMember neu setzen.

21.07.2006 - 15:24 Uhr

Es gibt eben nur zwei Methoden:

  1. Du benutzt RTB und führst deine schlankeren Funktionen auf RTB Funktionen zurück
  2. Du malst die komplette TextBox selbst. Also du schreibst eine eigene Paint Funktion. Das heißt dann du darfst dich ebenfalls um Zeilenumbruch und ums scrollen kümmern und all das schöne Zeug. Ziemlich viel Arbeit.

Die Idee "TextBox malt schonmal Text, jetzt muss ich den bloß noch färben" geht so nicht.

Aber viel Interessanter ist doch die Frage: Wie willst du es bitte einfacher machen als das was dir RTB anbietet? Zum Text einfärben gibt es ja nur zwei Methoden: Formatierter string übergeben oder Text auswählen und Eigenschaften festlegen. Beides beherrscht die RTB.

Wie du Keyword Highlightning machst steht ja schon in dem Link. Je besser die Regex sind umso schöner kanns werden.

21.07.2006 - 13:29 Uhr

Also ich persönlich fände es ziemlich cool, wenn man sowas wie die RTB hätte, der man aber statt RTB-Formatierten Text einen Latex-Formatierten Text übergeben könnte.

Jetzt nicht so in dem Umfang wie Latex mit Formeln und allem, aber eben die grundlegenden Textformatierungen. Schriftart, Farbe, Überschriften, Fett/Kursiv/Unterstrichen und solche Befehle eben mit dem Latex-Syntax.

Beispiel:

latexTextBox1.AppendLatex( @"\textbf{Hallo Welt}" ); // Hängt "Hallo Welt" fettgedruckt hinten ran

latexTextBox1.AppendLatex( @"\begin{tt}" ); // nachfolgender Text wird mit Typewriter Schriftart (z.B. Courier) geschrieben
latexTextBox1.AppendLatex( @"\end{tt}" ); // schaltet wieder auf normale Schriftart

21.07.2006 - 12:29 Uhr

Original von John Doe

Original von Cyron
Wäre eine Singleton-Klasse dafür geeignet?

Es gibt keine Singleton-Klasse; nur ein
>
. 😉

lg,
Johann

Ich liebe so schlaue Kommentare.

Eine Klasse, die ein Singleton ist, ist eine Singleton-Klasse.
Ein Pattern ist eben ein Entwurfsmuster.

Genauso könntest du sagen "Es gibt keine Dieselmotoren, es gibt nur Entwurfsmuster für Diesel betriebene Motoren"

20.07.2006 - 23:20 Uhr

Nur wenn die Tür zum Chef zu ist 😉

20.07.2006 - 23:13 Uhr

Mit Fremden zu entwickeln kann sehr anstrengend werden. Deswegen erstmal kleine Brötchen backen bis man sich etwas kennt.

Zeitplan ist gut, man muss nur auch berücksichtigen, dass es ein Freizeitprojekt ist. Also die Schätzungen schonmal pauschal verdoppeln 😉 Wenn was eher fertig ist, ist es einfacher den Zeitplan vor zu verlegen, als sich den Stress anzutun jemandem hinterherzulaufen und sich gegenseitig auf die Nüsse zu gehen.

Ich persönlich hab über Erweiterungen von existierendem Code ja das Programmieren angefangen. Ich kann mich ganz gut in was Bestehendes einarbeiten. Keine Ahnung wie es da anderen geht.

20.07.2006 - 10:35 Uhr

Für eine eigene Methode die man asynchron aufruft, kann man das auch relativ leicht basteln.

Man braucht nur in dieser Methode Thread.CurrentThread auf irgendeine Membervariable zuweisen, damit man von außen Abort aufrufen kann.