Laden...

Forenbeiträge von yngwie Ingesamt 238 Beiträge

04.04.2014 - 11:31 Uhr

yngwie ich glaub Du verwechselst da was.
Es wird keine zwei Verianten geben; es wird einfach einen zusätzlichen Build geben, der aus MSIL dann Native formt.
Source > MSIL > Native

Haste Recht, da habe ich es wohl erst falsch verstanden.

Reflection bleibt ebenfalls erhalten; der Entwickler muss bei eigenen Serialisierungen aber Metadaten mitliefern.

Was die Allmacht von Reflection angeht so wird diese merklich eingeschränkt (Zugrif auf private Member, erstellen von Instanzen von Typen mit generischen Parametern zur Laufzeit...)

04.04.2014 - 10:26 Uhr

Interessante und begrüßenswerte Entwicklung. Nun haben die C++ Kollegen keine Ausreden mehr a'la "ich verwende nicht C# weil es langsam ist" 😉

MS wird nicht auf dauer beide Varianten des .NET-Frameworks pushen können. Allein schon aus Kostengründen nicht. Ich schätze in 4-5 Jahren haben wir selbst auf Desktop nur das Native .NET. Oder sollte ich besser sagen "Unmanaged"? Was waren doch noch mal die oh so wichtigen Vorteile von ManagedCode vs Unmanaged auf die man jetzt offensichtlich doch so leich verzichten kann 😄

Übrigens wird es keine Reflection mehr geben. Ich kann mir vorsellen dass dies für relativ viele Produkte und kleine Tools ein ernstes Problem bedeutet. Arbeitet z.B. das Databinding nicht im Grunde auch auf Reflection?

21.10.2013 - 13:33 Uhr

Ich sage sogar noch mehr - für die nächste Produktversion werden wir voraussichtlich entsprechende Arbeitspakete einplanen um Syncfusion wider auszubauen.

16.10.2013 - 22:21 Uhr

Hatte sowohl mit WinForms als auch mit WPF-Komponenten von Syncfusion gearbeitet und kann, besonders die letzteren, leider nicht empfehlen. Wenn bei WinForms-Grids noch das größte Problem in der Komplexität der Architektur lag (die können zwar fast alles aber kein Mensch blickt es), so sind die WPF-Komponenten schlicht viel zu buggy 😦 Hoffe mein Feedback kommt für dich nicht zu spät...

21.04.2013 - 11:23 Uhr

Nicht jedes Verhalten ist einem Unit-Test zugänglich. Klarer wird es vielleicht, wenn du sicherstellen müsstest, dass ein Timer genau einmal Pro Stunde tickt, nicht mehr und nicht weniger. Da müsste dein Unit-Test mindestens eine Stunde laufen, eher mehr, und würde damit die schnelle Ausführbarkeit von Unit-Tests vereiteln.

Aber auch was kürzere Intervalle, kann es sein, dass das nicht in Unit-Tests gehört. Man würde ja auch nicht in einem Unit-Test testen, ob eine E-Mail tatsächlich versendet oder ob ein Dokument tatsächlich (physisch) gedruckt wird, sondern nur, ob die Methode zum Versenden bzw. Drucken aufgerufen wird.

Momentan würde ich mich weismat anschließen und sagen, das Timer-Verhalten muss gar nicht durch einen Unit-Test abgedeckt werden.

Hallo herbivore, weismat, Sarc

es macht tatsächlich Sinn. Habe nun ein Interface _:::

Das Problem ist gelöst:) Vielen Dank an alle die an der Diskussion teilgenommen haben.

16.04.2013 - 18:42 Uhr

mal eine ungewöhnliche Variante von
>
, aber letztlich genauso zu lösen, wie alle anderen Fälle von blockierten GUIs.

Der Code den ich oben gepostet habe ist nicht "buchstäblich" zu verstehen, es dient als Beispiel für die Problemstellung - wie kann man das Verhalten einer Klasse testen welches von einem Timer getrieben \ beeinflusst wird. Die Synchronization mit dem UI-Thread ist dabei nicht relevant (es sei denn ich verstehe dich gerade nicht richtig).

"Ich soll nach Möglichkeit einen Timer benutzen der im UI-Thread läuft" - ist keine harte Vorgabe. Kann stattdessen auch einen System.Timers.Timer nehmen...

Dein Test muss nicht testen, daß Framework/DispatcherTimer funktioniert, sondern, dass Deine Methode funktioniert.
Dafür müßtest Du einen Mock für den DispatcherTimer schreiben, der statt des DispatcherTimer aufgerufen wird und in den Asserts musst Du dann prüfen, daß die erwarteten Aufrufe für den Mock stattgefunden sind.

Hallo weismat,

für die Methode die vom Timer ausgelöst wird habe ich bereits Unittests geschrieben, das ist nicht das Problem. Was ich sicherstellen will ist dass die Timer-gesteuerte Verzögerung richtig greift. Der Gedanke den Timer zu mocken finde ich interessant. Bin mir allerdings noch nicht ganz sicher wie dieser Trick für meinen Testfall passt... Kannst du es eventuell in Anlehnung an meinen Beispielcode etwas detaillierter erklären? Wie würde meine Testmethode dann aussehen? Etwas Preudocode, keine fertige Lösung.

Gruß

15.04.2013 - 13:34 Uhr

Hallo Community,

folgende Ausgangssituation muss Unitgetestet werden:
*Habe eine Kasse "ItemVisitor" mit privater Liste von "Item"-Objekten. *ItemVisitor.AddItem() -> startet einen Verzögerungstimer welcher als Bremse für die Metode "Visit()" dient (siehe unten)
*Nur wenn der Timer abgelaufen ist wird die private Methode "ItemVisitor.Visit()" ausgeführt
*Kommt ein ItemVisitor.AddItem() bevor der Timer abgelaufen ist, wird der Timer verlängert bzw. neu gestartet *Ich soll nach Möglichkeit einen Timer benutzen der im UI-Thread läuft. Hier ist es der System.Windows.Threading.DispatcherTimer.

hier noch mal der Code von der Kasse:


using System;
using System.Linq;
using System.Timers;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Timer = System.Windows.Threading.DispatcherTimer;

namespace ProductiveCode
{
    public class Item
    {
        public int VisitCount;
    }

    public class ItemVisitor
    {
        private List<Item> items;
        private Timer delayTimer;
        public const int DELAY = 100;

        public ItemVisitor()
        {
            this.delayTimer = new System.Windows.Threading.DispatcherTimer();
            this.delayTimer.Interval = new TimeSpan(0, 0, 0, 0, ItemVisitor.DELAY);
            this.delayTimer.Tick += this.DelayTimerElapsedHandler;
            this.items = new List<Item>();
        }
        
        public void AddItem(Item item)
        {
            Tracer.TraceLine("Enter: ItemVisitor.AddItem()");
            Tracer.TraceLine("Retrigger delayTimer");

            this.items.Add(item);
            this.delayTimer.Stop();
            this.delayTimer.Start();

            Tracer.TraceLine("Exit: ItemVisitor.AddItem()");
        }

        private void DelayTimerElapsedHandler(object sender, EventArgs e)
        {
            Tracer.TraceLine("Enter: ItemVisitor.delayTimer_Elapsed()");
            this.VisitItems();
            Tracer.TraceLine("Exit: ItemVisitor.delayTimer_Elapsed()");
        }

        private void VisitItems()
        {
            Tracer.TraceLine("Enter: ItemVisitor.VisitItems()");

            this.isInVisit = true;
            this.delayTimer.Stop();

            foreach (Item item in this.items)
                item.VisitCount++;

            Tracer.TraceLine("Exit: ItemVisitor.VisitItems()");
        }
    }
}

Wie kann ich durch ein Unittest prüfen ob dieser "Verzögerungfilter" richtig funktioniert?
Mein erster naiver Test sieht so aus:


[TestClass]
namespace Unittests
{
    [TestClass]
    public class ItemVisitorTest
    {
        [TestMethod]
        public void Test_VisitWithDelay()
        {
            ItemVisitor itemVisitor = new ItemVisitor();
            List<Item> temp = new List<Item>();
            for(int i = 0; i < 4; i++)
            {
                Item item = new Item();
                temp.Add(item);
                itemVisitor.AddItem(item);
                Thread.Sleep(ItemVisitor.DELAY / 3);
                temp.ForEach(x => Assert.AreEqual(0, x.VisitCount, "Verzögerung greift nicht -> 'Visit()' gestartet zu früh!"));
            }
            Thread.Sleep(ItemVisitor.Delay * 2);
            temp.ForEach(x => Assert.AreEqual(1, x.VisitCount, "Nicht alle Items besucht, oder zu oft besucht!"));
        }
    }
}

Offensichtlich legt ein Thread.Sleep auch den Timer schlafen(Single-threaded Application), sodass diese Herangehensweise ungeeignet ist. Brauche ich hier einen separaten Thread oder gibt es andere elegante Möglichkeiten?

24.11.2012 - 16:54 Uhr

Hallo Community,

in meinem Programm muss ich nachschauen ob ein bestimmter Netzwerkadapter (z.B. der LoopbackAdapter) vorhanden ist. Folgender Code funktioniert unter WinXP:

 foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces()) // <- BUM
{
    if(networkInterface.Name == "Blubididub")
    {
        found = true;
        break;
    }
}

doch unter Win7 bekomme ich sporadisch eine NetworkInformationException "Zugriff verweigert". Hat jemand ähnliches beobachtet und wenn ja, wie kann man dieses Problem zuverlässig lösen?

08.08.2012 - 11:28 Uhr

Hallo GT71,

an sich eine sehr interessante Frage! Ich nehme an du arbeitest mit einem ORM-Tool (du erwähntest DBMS und DataContext)? EF ? Wenn ich es richtig verstehe möchtest du dass EF \ DataContext die Grösse aller Objekte im Objektgraphen ermitteln und aufsummieren soll, richtig? Und dass noch befor die Abfrage "materialisiert" wird (hier .ToArray()).

Nun ich will zwar nicht ausschliessen dass es dafür einen Trick gibt, bin aber erst mal sehr skeptisch ob das geht. Das Problem das ich hier sehe ist dass es in .NET leider keinen "Sizeof" operator für Referenztypen gibt. Das heisst EF hat gar keine technische Möglichkeit die Grösse einer Instanz zuverlässig zu ermitteln. Und selbst wenn es ginge, um die Objekte zu "wiegen" müsste EF diese vermutlich erst instanziieren (gerade das wolltest du ja vermeiden). Wenn du es "zu Fuß" machen willst dann wirst du ohne die Benutzung der Profiling-API es auch kaum hinkriegen 😦

Es wäre noch interessant zu überlegen ob man mit der Analyse der darunterliegenden Datenbanktabellen weiterkommt. Ansonsten bleibt dir tatsächlich nichts anderes übrig als zu Schätzen.

Gruß

08.08.2012 - 10:55 Uhr

Hallo serial,

das "billigste" wäre dafür zu sorgen dass die neuen Elemente immer an der letzten Position in der Liste auftauchen 😉

Gruß

13.07.2012 - 16:11 Uhr

Hallo herbivore,

... ok, wenn du eine eigene thread-safe BindingList verwendest und auch alle direkt und indirekt in dieser BindingList enthaltenen Objekte, deren Properties, Methoden, Events usw. von sich heraus thread-safe sind, würde es vielleicht gehen...

ach nein, so aufwändig muss man es wirlich nicht machen. Zum "aufzeigen" bin ich zu faul, ich sage nur dass der Enumerator in einem typischen Databinding-Scenario keine Rolle spielt. Du kannst mal nach "AsyncBindingList" googlen und dich von der Demoapp überzeugen lassen 😉 Und was die Bedeutung für die Praxis angeht... nun nicht selten steht man vor der Aufgabe ein sogenanntes "responsive UI" zu realisieren. Mit einer angepassten BindingList kann man diese Arbeit schneller erledigen und dabei das Komfort von Databinding geniessen. Finde ich äußerst praxisrelevant 😉

Gruß

13.07.2012 - 10:01 Uhr

Hallo herbivore,

...falls eine andere Synchronisation mit dem GUI-Thread möglich wäre, wäre das ausreichend, aber sie ist nicht möglich...

Wieso ist sie denn so kategorisch nicht möglich? Ich habe eine BindingList implementiert die neben Suchen und Sortieren sich bei Bedarf auch noch mit dem UI-Thread synchronisiert. Diese verwende ich fürs Databinding, sogar im Produktivumfeld... funktioniert sehr gut.

13.07.2012 - 09:45 Uhr

Hallo Siedlerchr,

Die Liste die als DataSource am DGV hängt wird von einem Thread in 1000 Schritten befüllt
das ist nicht erlaubt und kann zu abstrusen Fehlern führen...

Das mit "nicht erlaubt" finde ich etwas zu scharf formuliert... Sagen wir es mal so, wenn deine (Sortable)BindingList Implementierung sich intern mit dem UI-Thread synchronisiert, dann würde herbivore es erlauben, oder? 😉

Siedlerchr, was ich irgendwie nicht ganz verstehe ist die Kombination aus VirtualMode und einer DataSource... Macht so etwas Sinn, bzw schliesst es sich nicht gegenseitig aus? Kannst du eventuell mal einen Link posten wo man über diese Art der Datenbindung nachlesen kann?

12.07.2012 - 16:56 Uhr

Hallo Rahvin,

versuche doch einfach mal das entsprechende Klick-Ereignis vom Spaltenkopf bzw. DataGrid zu abonieren und mache dann sowas wie:


/// (Pseudocode):
private void SpaltenkopfKlickHandler(object sender, IrgendwelcheEventArgs e)
{
    DataGridView grid = sender as DataGridView;
    IList list = grid.DataSource as IList;
    list.Sort(e.Ascending);
    grid.DataSource = null;
    grid.DataSource = list;
    grid.Refresh();
}

Oder wie herb es vorschlägt kannst du deine Liste in eine BindingList reinpacken und and das Grid binden grid.DataSource = new BindingList(deineListe);
Grüßle

05.07.2012 - 14:00 Uhr

Vielleicht probierst du OneWay databinding anstatt TwoWay zu verwenden (wenn ich richtig verstehe was du machen willst).

05.07.2012 - 13:43 Uhr

Hallo TLoD,

leider muss man sich hier selbst um das Layout kümmern. Ich würde es mal nach folgendem Algo aufziehen:

  1. Gehe über alle Spalten und Zeilen und finde den längsten Text in jeder
  2. Bei Wunsch kann der Text um 1-2 beliebige Zeichen erweitert werden um später Spaltenabstände zu realisieren
  3. Lege das Ergebnis in einer Dictionary ab wo Schlüssel = Spaltenname; Wert = Längster Text ist
  4. Gehe über alle Values im Dictionary und bilde die längste Zeile durch das Anhängen der Texte aneinnander
  5. Mimm ein beliebiges Font (z.B. von ListView), miß die Textbreite der längsten Zeile mit Graphics.MeasureText(... )
  6. Wenn die Zeilenbreite > Seitenbreite ist, verkleinere Font.Size (-0.25f) und wiederhole Schritt 5 bis die Zeile reinpasst.
  7. Nun da du den passenden Font hast kannst du die Anzahl der Zeilen ermitteln die auf eine Seite passen werden.
  8. int zeilenProSeite = Seite.Heigth / (Zeilengröße.Heigth aus Schritt 5); e.HasMorPages = ListView.Items.Count ≤ zeilenProSeite;
  9. Die optimale Spaltenbreite kann leicht berechnet werden mit Graphics.MeasureString(Dictionary[spaltenname]);
  10. An diesem Punkt haben wir alles was wir zum Zeichnen brauchen - optimale Spaltenbreiten, die Zeilenhöhen, Font, Zeilenanzahl
  11. Jetzt noch 2 verschachtelte Schleifen bilden und jede "Zelle" und mit Graphics.DrawRectangle() + Grahpcs.DrawString() zeichnen.
  12. Eventuell noch die Seitennummer merken, um bei mehrseitigen Drucks beim richtigen index weiterzudrucken (ListView.Items[index]).

Gruß

13.06.2012 - 09:07 Uhr

Hallo smalldevice,

wenn ich es richtig verstehe möchtest du ein Mix aus TreeView und DataGrid haben richtig? Oder soll eher in einer bestimmten Tabellenspalte jede Zelle einen kleinen Baum enthalten? Beides kann recht aufwendig\kompliziert werden, besonders wenn es mit sauberem Databinding ausgestattet werden soll. In WinForms gibt es leider gar keine fertige Databinding-Mechanizmen für hierarchisch strukturierte Daten (hier Bäume). Wenn kaufen gar nicht geht dann melde dich wieder, mal schauen was sich so machen lässt 😉

PS: kannst du eventuell eine Skizze anheften wie das Control ausschauen soll.

05.12.2011 - 16:25 Uhr

Sorry Darth Maim aber wie bereits in meinem Originalpost beschrieben funktioniert es nicht zusammen mit "Enabled = false" wie gewünscht

05.12.2011 - 13:17 Uhr

Hallo BerndFfm,

die beschriebene Variante mit Cursor.Current hätte leider den Nachteil dass gleich die ganze Oberfläche der Applikation betroffen ist. Ich muss ganz gezielt nur bestimmte Controls "sperren". Trotzdem danke ich dir für deine Antwort.

Gruß

05.12.2011 - 00:26 Uhr

Hallo Community,

in meiner Applikation habe ich eine längere Operation die asynchron im BackgroundWorker ausgeführt wird (es wird auch wo nötig ins UI-Thread synchroniziert). Für die Dauer dieser Operation muss ich ein paar Steuerelemente sperren und deren Cursor - Eigenschaft auf WaitCursor setzten. Getrennt betrachtet machen die Eigenschaften "Enabled" und "Cursor" keine Probleme doch zusammen funktioniert es einfach nicht. Sobald Enabled auf "false" gesetzt wird verwirft das Control den Wert von der Cursor-Eigenschaft und es wird immer nur ein Default Cursor angezeigt. Sprich ich bekomme entweder ein Disabled oder ein WaitCursor aber nicht beides gleichzeitig. Hat eventuell jemand schon mal solches Problem erfolgreich gelöst? Bitte um Hinweise.

PS: Einfaches setzen vom WaitCursor genügt leider nicht da es danach immer noch möglich ist auf dem Control zu clicken:baby: .

Gruß

28.08.2011 - 15:05 Uhr

Hallo Community,

mich hätte es mal interessiert ob es ein MVVM-Framework gibt welches unter Mono verwendet werden kann. Kann z.B. Prism unter Mono kompiliert und verwendet werden? Leider hat Mister Google nicht viel nützliches dazu ausgespuckt (ausser vielleicht "MonoCross"). Hat jemand bereits praktische Erfahrungen damit gemacht?

Gruß

24.11.2010 - 23:03 Uhr

Hallo herby, du hast natürlich Recht, so ganz ohne Code ist es einfach zu abstrakt 😃


// Assembly 1 -> TestTraceListener 
public sealed class TestTraceListener : TextWriterTraceListener
{
	private static TestTraceListener instance;
	private static readonly object lockObject = new object();
	
	// privater Konstruktor
	private TestTraceListener()
	{
	}
	
	// Singleton impl.
	public TestTraceListener Instance
	{
		get
		{
			lock(TestTraceListener.lockObject)
			{
				if(TestTraceListener.instance == null)
				{
					TestTraceListener.instace = new TestTraceListener();
				}
				return TestTraceListener.instance;
			}
		}
	}
	
	public override void Write(string message)
	{
		lock(TestTraceListener.lockObject)
		{
			base.Write(message);
		}
	}
	
	public override void WriteLine(string message)
	{
		lock(TestTraceListener.lockObject)
		{
			base.WriteLine(message);
		}
	}
}

// Assembly 2 -> In dieser (hier voellig sinnlosen) TestKlasse will ich den TestTracer benutzen
[Nunit.Framework.TestFixture]
public class SomeTestClass
{
	// Benoetigt folgende Referenzen: 
	// - nunit.framework.dll 
	// - Assembly 1
	
	[Nunit.Framework.Test]
	public void TestAddition()
	{
		int a = 3; int b = 2; 
		Nunit.Framework.Assert.AreEqual(5, a + b, "Wrong result!");
		TestTracer.Instance.WriteLine("Greetings from inside of 'TestAddition'");
	}
	
	[Nunit.Framework.Test]
	public void TestSubstraction()
	{
		int a = 3; int b = 2; 
		Nunit.Framework.Assert.AreEqual(1, a - b, "Wrong result!");
		TestTracer.Instance.WriteLine("Greetings from inside of 'TestSubstraction'");
	}
	
	[Nunit.Framework.Test]
	public void TestMultiplication()
	{
		int a = 3; int b = 2; 
		Nunit.Framework.Assert.AreEqual(6, a * b, "Wrong result!");
		TestTracer.Instance.WriteLine("Greetings from inside of 'TestMultiplication'");
	}
}

// Assembly 3 -> Hier befindet sich meine NUnit-AddIn Implementierung 
[NUnit.Core.Extensibility.Addin]
public class NUnitEventListenerAddIn : EventListener, NUnit.Core.Extensibility.IAddin
{
	// Benoetigt folgende Referenzen: 
	// - nunit.core.dll 
	// - nunit.framework.dll 
	// - nunit.core.interfaces.dll
	// - Assembly 1
	
	#region IAddin Members
	
	public bool Install(IExtensionHost host)
	{
		IExtensionPoint listeners = host.GetExtensionPoint("EventListeners");

		if (listeners == null)
			return false;

		listeners.Install(this);
		return true;
	}
	
	#endregion IAddin Members
	
	#region EventListener Members

	public void SuiteStarted(TestName testName)
	{
		// Einrueckung vergroessern und tracen 
		TestTracer.Instance.Indent++;
		TestTracer.Instance.WriteLine("SuiteStarted: " + testName.Name);
	}
	
	public void SuiteFinished(TestSuiteResult result)
	{
		// tracen und Einrueckung verkleinern
		TestTracer.Instance.WriteLine("SuiteFinished: " + result.Name)
		TestTracer.Instance.Indent--;
	}
	
	public void TestStarted(TestName testName)
	{
		// Einrueckung vergroessern und tracen 
		TestTracer.Instance.Indent++;
		TestTracer.Instance.WriteLine("TestStarted: " + testName.Name)
		TestTracer.Instance.Indent++;
	}
	
	public void TestFinished(TestCaseResult result)
	{
		// tracen und Einrueckung verkleinern
		TestTracer.Instance.Indent--;
		TestTracer.Instance.WriteLine("TestFinished: " + result.Name)
		TestTracer.Instance.Indent--;
	}

	// weitere Event Handler nach dem gleichen Schema F...
	public void RunFinished(Exception exception){}
	public void RunFinished(TestResult result){}
	public void RunStarted(string name, int testCount){}
	public void TestOutput(TestOutput testOutput){}
	public void UnhandledException(Exception exception){}

	#endregion EventListener Members
}

Die Ausgabe soll dann in etwa so aussehen:

[pre]
RunStarted: Assembly2.dll
    SuiteStarted: SomeTestClass
        TestStarted: TestAddition
            Greetings from inside of 'TestAddition'
        TestFinished: TestAddition	
        TestStarted: TestSubstraction
            Greetings from inside of 'TestSubstraction'
        TestFinished: TestSubstraction	
        TestStarted: TestMultiplication
            Greetings from inside of 'TestMultiplication'
        TestFinished: TestMultiplication	
    SuiteFinished: SomeTestClass
RunFinished: Assembly2.dll
[/pre]

Bitte beachte dass die Einrueckung von <Greetings from inside of '...'> in der TestMethode nicht gesetzt werden muss weil es bereits im NUnit-AddIn gesetzt wurde und wir ja überall auf der gleichen Singleton-Instanz arbeiten.

Damit das NUnit-AddIn geladen wird muessen Assembly1 + Assembly3 in das Installationsverzeichnis von NUnit\bin2.0\addins kopiert werden. Wenn ich dann NUnit-GUI starte und es über Assembly2 jage hängt es sich auf. Im "Threads" Window sehe ich wie sich 2 Threads gegenseitig blokieren.

Gruß

24.11.2010 - 19:08 Uhr

Hallo Leute,

ist es möglich eine Klasse die als Singleton implemeniert ist auch noch ThreadSafe zu machen?

Der Hintergrund: ich suche nach einer generischen Möglichket NUnit-Tests zu tracen. Habe gerade ein NUnit-AddIn geschrieben und abonniere alle relevanten Events beim Starten und Beenden einer TestSuite & eines TestMethods. In den Eventhandlern will ich lediglich nur eine Zeile tracen:


public void TestStarted(NUnit.Core.TestName testName)
{
TestTraceListener.Instance.IndentLevel++;
TestTraceListener.Instance.WriteLine("Enter method: " + testName.Name);
}

Der TraceListener ist in einem eigenem Assembly untergebracht und soll deswegen ein Singleton sein damit ihn sowohl im NUnit-AddIn als auch in den eigentlichen Tests die gleiche Instanz benutzen kann. Threadsicher muss die Klasse sein weil NUnit u.U. mehrere Threads aufzieht um seine Tests schneller abzuarbeiten und es zu sog. racing conditions kommen kann. Mit einem einfachen "lock" bin ich bis jetzt nicht weit gekommen, mache ich was falsch?

Gruß

19.11.2010 - 00:28 Uhr

@Binärathlet,

wenn ich nun aber dem Nutzer verbiete, Zeilen hinzuzufügen oder zu löschen, enthält das DataGridView auf einmal gar keine Einträge mehr

für das Grid ist es das gleiche als hättest du es implicit auf "ReadOnly" gesetzt, vermutlich bleben die ComboBoxen deswegen leer.

BITTE, BITTE, BITTE schaue dir doch ENDLICH die Lösungsvorschläge an die dir Community gibt !!! ErfinderDesRades, recmar, und meine wenigkeit hatten dir schon vor 2 Wochen funktionierende Beispiele angeboten (sogar mit Databinding und Indexsetzen) !!! Auch FZelle gibt dir einen sehr wertvollen Tipp

Du sollst die Daten nicht ins Grid frickeln, sondern die Daten Binden ( DataTable?! )

Einfach nur systematisch die gegebene Info durcharbeiten...

10.11.2010 - 16:43 Uhr

Hallo ibaxx,

das beste ist immer noch wenn man alles selbst macht - die grösste Kontrolle !
Schaue dir doch ein mal das Attachement an, da habe ich das Konzept mal groß skizziert.

Gruß

08.11.2010 - 23:16 Uhr

Hallo Binärathlet,

wenn du mir jetzt noch sagen könntest, wie ich den Index festlege

dir wurden drei Lösungsvorschläge (fast schon Musterlösungen) presentiert und die Antwort auf deine Frage ist defenitiv dabei... Du musst dich jetzt auch mal anstrengen!

😄

03.11.2010 - 10:06 Uhr

Also ich würde es in etwa so machen:


#region Create and fill the main data table

// Tabelle mit den eigentlichen Daten
DataTable mainData = new DataTable("Main";);
mainData.Columns.Add("FirstName", typeof(string));
mainData.Columns.Add("LastName", typeof(string));

DataRow person1 = mainData.NewRow();
person1["FirstName"] = "Joe";
person1["LastName"] = "Satriani";

DataRow person2 = mainData.NewRow();
person2["FirstName"] = "Juergen";
person2["LastName"] = "Drews";

mainData.Rows.Add(person1);
mainData.Rows.Add(person2);
mainData.AcceptChanges();

#endregion Create and fill the main data table

#region Create and fill additional data table

// Tabelle mit den Werten fuer die ComboBox
DataTable additionalData = new DataTable("Additional";);
additionalData.Columns.Add("Rating", typeof(string));

DataRow awesomeRating = additionalData.NewRow();
awesomeRating["Rating"] = "Awesome";

DataRow goodRating = additionalData.NewRow();
goodRating["Rating"] = "Good";

DataRow terribleRating = additionalData.NewRow();
terribleRating["Rating"] = "Terrible";

additionalData.Rows.Add(awesomeRating);
additionalData.Rows.Add(goodRating);
additionalData.Rows.Add(terribleRating);
additionalData.AcceptChanges();

#endregion Create and fill the additional table

#region Create and fill dataSet

DataSet dataSet = new DataSet();
dataSet.Tables.Add(mainData);
dataSet.Tables.Add(additionalData);

#endregion Create and fill dataSet

#region Create and fill the ComboBox-Column

DataGridViewComboBoxColumn ratingColumn = new DataGridViewComboBoxColumn();
ratingColumn.Name = "Rating";
ratingColumn.HeaderText = "Rating";
ratingColumn.HeaderCell.Value = "Rating";
ratingColumn.DataPropertyName = "Rating";
ratingColumn.DataSource = dataSet.Tables["Additional"];
ratingColumn.ValueMember = dataSet.Tables["Additional"].Columns["Rating"].ColumnName;
ratingColumn.DisplayMember = dataSet.Tables["Additional"].Columns["Rating"].ColumnName;

#endregion Create and fill the ComboBox-Column

#region Bind data to the grid and attach a comboBoxColumn

this.dataGridView.DataSource = dataSet;
this.dataGridView.DataMember = dataSet.Tables["Main"].TableName;
this.dataGridView.Columns.Add(ratingColumn);
this.dataGridView.ReadOnly = false;

#endregion Bind data to the grid and attach a comboBoxColumn

#region Set custom values for 'Rating' cells

DataGridViewComboBoxCell person1ComboBoxCell = (this.dataGridView.Rows[0].Cells["Rating"] as DataGridViewComboBoxCell);
person1ComboBoxCell.Value = ((DataTable)person1ComboBoxCell.DataSource).Rows[0]["Rating"];

DataGridViewComboBoxCell person2ComboBoxCell = (this.dataGridView.Rows[1].Cells["Rating"] as DataGridViewComboBoxCell);
person2ComboBoxCell.Value = ((DataTable)person1ComboBoxCell.DataSource).Rows[2]["Rating"];

#endregion Set custom values for 'Rating' cells

03.11.2010 - 09:37 Uhr

Hi binärathlet,

  • wie sind die Daten and das Grid gebunden? Sind es Collections, DataTables... ?
  • brauchst du eventuell ganze ComboBox-Spalten oder müssen es wirklich einzelne ComboBox-Zellen sein?

Gruß

26.10.2010 - 17:13 Uhr

@gfoidl,

Danke, funktioniert prima!

@Floste

hatte vergessen zu erwähnen dass ich mitm .NET Framework 2.0 arbeite 😦 Trotzdem vielen Dank

26.10.2010 - 16:46 Uhr

Hallo Community,

ich habe eine Variable 't' vom Type 'System.Type' und möchte zur Laufzeit eine entsprechende generische Liste erstellen. Nur wie mache ich das eigentlich - new List<t.GetType()> geht ja nicht... Vorschläge?

Gruß

23.07.2010 - 15:59 Uhr

Hallo,

beim debuggen bringt das VisualStudio viel zu oft eine Dialogbox mit der Meldung "A first change Exception of type..." hoch - das nervt gewaltig. In den meisten Fällen ist so eine "first chance"-Exception völlig harmlos und deswegen reicht es mir wenn solche Meldungen im Output-Window auftauchen und die Dialogbox erst gar nicht aufpoppt. Bin mir relativ sicher dass die Dialogbox sich irgendwie auschalten lässt... Weiss jemand welchen Hacken ich wo im VS2005 dafür setzten/rausnehmen muss?

Gruß

18.02.2010 - 21:41 Uhr

Das:

klar.. man kann auch per reflection.emit code einschleusen, das eine native dll generiert und compaliert, welche dann automatisch gestartet wirt, welches dann einen dienst erzeugt und registriert, welches dann alle 50 ms auf den ordner geht und die datei pollt um dann per remoting der ursprünglichen anwendung eine message zu schicken, damit diese weiß das sich etwas geändert hat.

ist eine sehr interessante Idee 😃

und das:

das allerdings liegt höchst wahrscheinlich nciht am filesystemwatcher sondern an deiner art der stringverkettung.

eine gewagte Annahme 😄

Übrigens, die Verzögerung scheint durch die Bufferung des in A verwendenten TraceWriters zu entstehen - behoben durch das regelmäßige Aufrufen von Flush() 😛

18.02.2010 - 21:30 Uhr

Oder versuchs mal mit nem FileSystemWatcher

Sorry aber du hast mein Post nicht (aufmerksam) gelesen - ich verwende bereits einen FileSystemWatcher 😦

18.02.2010 - 21:28 Uhr

Hallo Marsti,

ja beide Anwendungen sind von mir. Wie genau kann Anwendung A eine Nachricht an B schicken (wenigstens ein Stichwort) und wie schnell ist so etwas?

17.02.2010 - 23:57 Uhr

Hallo,

folgendes Problem gilt es zu lösen:

  • Application A schreibt sporadisch Meldungen in eine Textdatei
  • Application B (anderer Prozess) liesst aus dieser Textdatei und zeigt den Inhalt in ihrer Textbox an
  • Wie kann Application B möglichst zeitnah merken dass der Inhalt der Textdatei verändert wurde?

Momentan probiere ich dass sich B über einen FilesystemWatcher updatet - wenn allerdings A anfängt die Meldungen sehr oft auszuspucken dann kommt der FilesystemWatcher mit seien Events nicht mehr hinterher und die TextBox aktualisiert sich mit grösserer Verzögerung. Mir ist klar dass bei dieser Geschwindigkeit kein Mensch die TextBox mitlesen kann; dennoch -> kennt vielleicht jemand andere/performatere Ansätze wie B Änderungen an dieser Textdatei mitkriegen kann?

Danke

14.01.2010 - 15:35 Uhr

Hallo Community,

ich such nach einer Möglichkeit den Click auf den Ok bzw. Save-Button des SaveFileDialoges programmatisch zu simulieren. Mein erster Gedanke war über Reflaction zu gehen, doch wenn ich mir die Innereien von dem Dialog in Reflector anschaue dann stelle ich fest dass es da gar keinen Ok-Button gibt. Der nächste Ansatz war es den Click über die Accessibility-Schnittstelle auszulösen. Hier fand ich schnell heraus dass keines der Dialoge ein AccessibleObject zur verfügung stellt (obwohl es im AccExplorer trotzdem irgendwie funktioniert). Als letztes bleibt mir wohl das direkte Senden einer entsprechenden WinMessage and das DialogFenster... Leider bringe ich deises nicht zusammen weil ich nur sehr wenig Erfahrung mit Win32-API & Messages habe... Könnte mir da vielleicht jemand weiterhelfen ?

Gruß

07.12.2009 - 23:23 Uhr

Hallo Tschebbe,

wenn ich es richtig verstehe möchtest du die listen alphanumerisch sortieren - dafür benötigst du einen entsprechenden comparer. Leider gibt es im .NET-Framework (meines wissens nach) nix passendes 😦 Falls du eine ähnliche sortierung haben möchtest wie es der win-explorer macht dann kannst du mittels pinvoke auf StrCmpLogicalW zugreifen...

Gruß

02.08.2009 - 17:55 Uhr

Hi Peter,

danke für den Link! Der Anfang sieht vielversprechend aus... warte auf den zweiten Teil

Gruß

02.08.2009 - 13:23 Uhr

Hallo winSharp93,

Muss dazu die ganze Anwendung gestartet sein und die Objekte aus einer anderen Anwendung stammen

ich muss testen können ob vorgenommene Änderungen auch nach dem Restart der Application noch da sind (sauber in der DB abgelegt sind + wieder in die BusinessObjekte geladen). Dafür müsste ich die "Application under test" von aussen starten, beenden und restarten können... das ist einer der Gründe warum ich der Meinung bin dass eine zweite "Application" notwendig ist. Kennst du einen anderen Weg so etwas umzusetzten?

Warum testest du dann nicht die Commands direkt? Kannst du vielleicht diesen Gedanken etwas ausführlicher beschreiben, ich versteh es gerade nicht 😦 Danke

01.08.2009 - 22:13 Uhr

Hi winSharp93

UnitTests sollten möglichst unabhängig von der konkreten Anwendung durchgeführt werden (vor allem vom UI).

durch die Benutzung von Commands sollten die Tests relativ unabhängig vom UI sein.

Was die Unabhängigkeit von der konkreten Anwendung angeht ... 🙂 🙂 🙂 ...
Leider müssen die Tests im nachhinein geschrieben werden, da die Application schon längst fertig ist... d.h. es wird immer noch punktuell daran geschraubt, und dadurch dass die Architektur relativ unflexibel ist geht öfters mal nach einem BugFix irgend-etwas anderes kapputt. Oft muss dann an zig Stellen überprüfen werden ob alles noch OK ist, bzw. wo was nicht mehr stimmt. Deswegen sehe ich meine Tests einem Integrationstest am ähnlichsten und bin mir nicht ganz sicher ob die reine Lehre vom Aufbau der UnitTests hier 100%ig angewendet werden kann 😉

Was ich sagen will: Auch größter technischer Aufwand kann Versäumnisse beim Design hin zu testbaren Objekten nicht wettmachen.

Genau ! (und ich muss jetzt versuchen das Beste daraus zu machen)

um später Mocks und Stubs einsetzen zu können

Das stimmt natürlich. Bei mir ist die Versuchung recht groß die bestehende "Infrastruktur" zum Testen zu nutzen - sprich statt zu Mocken den existierenden Context zu verwenden.

Anders sieht es aus, wenn du das UI testen möchtest: Hier solltest du UI Automation verwenden

Nein nein, gerade die Oberfläche will ich ja gar nicht testen. Die meisten Aktionen werden zwar durch die Oberfläche getriggert, senden aber unter der Haube Commands zum CommandProcessor. Genau dies hoffe ich mir in meinen Tests zu nutze machen zu können um die Anzahl der LOCs im Testcode zu minimieren.

Es ist etwas kompliziert... so ein Kommando muss erst duch 3 Layer geschleift werden bis es in der eigentlichen BusinessLogic landet (deren Konsistenz interessiert mich am meisten) - und mit meinen Tests will ich sicherstellen das das Kommando unterwegs nicht kaputt gegangaen ist usw... Weiss echt nicht wie ich es sonst machen kann.

01.08.2009 - 20:53 Uhr

Hallo Leute,

ich habe eine WindowsApplication die ich durchtesten will (ähnlich Integrationstest). Fast alle GUI-Click-Aktionen senden intern Commands (das Command-Pattern). Nun habe ich mir folgendes überlegt: Ich würde ein zweites Assembly namens "Test" (eine Klassenbibliothek) erstellen wo die Klassen mit UnitTests existieren sollen. Die Testmetoden darin könnten z.B. so aussehen:

1.) mache die alte Datenbank platt
2.) starte die WinApplication (Process.Start()?)
3.) hole aus WinApplication-Assembly eine Referenz auf das Objekt welches für Commands zuständig ist (Reflection?)
4.) manipuliere die DomainObjekte durch das versenden entsprechender Commands (new/delete/alter usw...)
5.) prüfe das Ergebnis mit Asserts
6.) beende die WinApplication

Dabei sind mir einige Punkte nicht ganz klar:
1.) werde ich bei dieser Vorgehensweise drei separate Processe am laufen haben - für NUnit, WinApplication und die Test.dll?
2.) mit welchen Problemen muss ich rechnen wenn die Test.dll und WinApplication.exe tatsächlich in zwei eigenständigen Processen laufen?
3.) Kann ich dann trotzdem aus Test.dll heraus auf die .NET-Objekte der WinApplication zugreifen?

Gerne würde ich ein paar Meinungen zu diesem "Konzept" hören. Kritik, Alternativvorschläge, technische Hinweise ... immer her damit 😃

13.06.2009 - 13:33 Uhr

Hallo Froggie,

es gibt ein kostenloses AddIn fürs VisualStudio namens "TytanNET", schaue dir dort die sog. "DebugView" an - die kann es.

Gruß

13.06.2009 - 13:26 Uhr

Hallo lindesbs,

bei FxCop gibt es eine Rule die Kodeleichen innerhalb eines Assembly finden kann. Alternativ könntest du ein eigenes kleines Analysetool schreiben welches mittels Reflection alle Assemblies aus einem bestimmten Ordner lädt und scannt. Um festzustellen ob eine Klasse/Methode in einem anderen Assembly verwendet wird brauchst du nur ihre eindeutige Signatur (d.h. es müssen berücksichtigt werden die: AssemblyName+TypeName+MethodName+eindeutige Signaturen aller Argumente) als ein Key im Dictionary abzulegen, danach zu suchen und den "Verwendet"-Counter hochzuzählen... Anschliessend kannst du dir alles mit Count==0 ausgeben lassen. Tipp am Rande: der Suchaufwand lässt sich stark reduzieren wenn du die Abhängigkeiten deiner Assemblies untereinander berücksichtigst und die Assemblies des .NET-Frameworkes komplett überspringst. Hatte mal angefangen etwas ähnliches zu schreiben doch dann mangels Zeit wieder eingestellt. Eine nicht optimierte Variante benötigte damals (ohne Multithreading) ca. 2 Stunden für 20 Assemblies. Es waren auch ein paar "false positives" dabei - d.h. mein Algo/Keys war noch nicht gut genug. Ich schätze eine einfache Version von solch einem Tool kann man in ca. 2 Tagen pogrammieren... und dann geht es wie immer nach der alten Formel: "Restliche 20% der Funktionalität in 80% der Zeit" 😃

Gruß

01.06.2009 - 20:21 Uhr

Hi ikaros,

der Meinung bin ich auch 😃 nur wie lässt sich das im VS2008 einstellen?

01.06.2009 - 15:54 Uhr

Hi peoples,

folgendes Problem: auf meinem Notebook sind alle debug Visualizers standardmäßig unter "Eigene Dateien\VisualStudio2008\Visualizer" zu finden. Wenn ich aber unterwegs bin so ist der Ordner "Eigene Dateien" nicht mehr verfügbar - ist von der Firma als Netzlaufwerk konfiguriert. Beim Debuggen vermisse ich somit schmerzlichst die praktischen DebugVisualizers für DataTable/DataView 😦 Suche nach einer Möglichkeit das VisualStudio umzukonfigurieren, damit es den Visualizers-Ordner lokal ablegt/verwendet... leider ist es mir bis jetzt nicht gelungen eine solche Einstellung zu finden - weiss jemand Rat?

Gruß

12.02.2009 - 16:52 Uhr

Hallo Leute,

ich möchte gerne dass meine Assembly im Windows-Explorer mit einem Icon angezeigt wird welches ich als Resource in diese Assembly einbette. Klingt eigenlich trivial aber irgendwie klappt es bei mir nicht. Habe Bitmaps (250x250, 64x64, 32x32 und 16x16) in die Assembly eingebettet. Wenn das Format eine entscheidende Rolle spielt und es unbedingt Icons sein müssen, dann brauche ich einen Weg wie ich aus einem Bitmap ein Icon schnitzen kann (brauche ich dazu Tools)?

Danke für jede Hilfe und Gruß

14.01.2009 - 19:24 Uhr

Danke für eure Antworten,

@Feuerfalke:
Leider kann ich den Code nicht manipulieren da diese Assembly bereits beim Kunden draussen ist.

@winSharp93:
Habe es mit deiner Lösung noch vor dem Posten schon probiert und es klappte leider nicht. Nun weiss ich auch wieso -> die fatale Exception wurde offensichtlich noch VOR dem Eintritt in die Main-Methode geworfen (aus dem BCL heraus), deswegen kamm ich auch nie in meinen Breakpoint rein und dachte schon dass ich irgendetwas falsch mache...

Danke noch mals an alle 😃

14.01.2009 - 18:21 Uhr

Hallo,

ich muss eine laufende Applikation debuggen (habe dazu auch die Sourcen und PDBs), mein Problem dabei ist - diese .exe stürzt bereits 1 Sekunde nach dem Start ab und somit schaffe es einfach nicht mich an diesen Process mit "VisuaStudio/Debug/Attach to Process" dranzuhängen 😦 Hat jemand eine Idee wie man sowas debuggt?

Danke

23.12.2008 - 00:25 Uhr

Hallo See Sharp,

folgendes Dokument scheint deine letzte Frage ganz gut zu beantworten. Zugegeben es ist schon etwas älter aber dennoch sehr empfehlenswert da es ganz klar die Richtung angibt. Linq to Xml ist darin natürlich nicht behandelt - ich habe aber gelesen dass es performanter als XmlDocument ist.

Gruß