Laden...

Forenbeiträge von impact Ingesamt 332 Beiträge

16.04.2014 - 16:01 Uhr

Hallo,

wir haben einen TFS 2012 und auf diesem komplett eigene WorkItem-Types erstellt. Der letzte State aller unsere WorkItem-Types ist nicht "Closed" wie üblich, sondern "Completed".

Daher sind die "Resolved Date" und "Closed Date" Spalten immer leer, wenn man diese WorkItems auflistet.

Frage:
Wie erreiche ich, dass in den o.g Spalten angezeigt wird, wann unsere WorkItems "Completed" wurde ?

Gruß,
Holger

24.10.2013 - 23:42 Uhr

Hallo,
an diesem Problem hänge ich seit Tagen:

  • TFS2010 Server
  • TFS2010 TeamBuild auf Win7 installiert
  • VS2010 und VS2012 sind auf dem Build-Server installiert
  • Target-Framwork der Projekte ist .net 4.5
  • die Tests laufen in VS, aber nicht auf dem Build Server
  • Jeder Test wird als "Not Executed" angezeigt

Jetzt das Wesentliche: Laut Log (unten angehängt) wird die DLL
Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo.dll nicht gefunden. Diese DLL befindet sich nicht auf dem Computer und auch im Internet gibt es keinen Hinweis darauf, wozu die DLL eigentlich gehört. Könnt Ihr mir weiterhelfen ?

Gruß,
Impact

Hier der Error aus dem Log:

Fehlermeldung:
Error 10/24/2013 10:41:59 PM The diagnostic data adapter 'Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo.SystemInfoDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' on agent 'DTDE6046' threw an exception during type loading, construction, or initialization: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.VisualStudio.TestTools.DataCollection.SystemInfo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError)
at Microsoft.VisualStudio.TestTools.DataCollection.ExecutionPluginManager.LoadAndInitDataCollectorAsync(TestRun testRun, String collectorTypeName, Dictionary`2 dataCollectorCache)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
. DTDE6046
Error 10/24/2013 10:41:59 PM The diagnostic data adapter 'Microsoft.VisualStudio.TestTools.DataCollection.EventLog.EventLogDataCollector, Microsoft.VisualStudio.TestTools.DataCollection.EventLog, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' on agent 'DTDE6046' threw an exception during type loading, construction, or initialization: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.TestTools.DataCollection.EventLog, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.VisualStudio.TestTools.DataCollection.EventLog, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError)
at Microsoft.VisualStudio.TestTools.DataCollection.ExecutionPluginManager.LoadAndInitDataCollectorAsync(TestRun testRun, String collectorTypeName, Dictionary`2 dataCollectorCache)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
. DTDE6046

18.06.2013 - 13:46 Uhr

Hallo,
gibt es eine Möglichkeit die Größe einer bestimmten Datei in der VersionControl herauszufinden, ohne sie herunterzuladen ? Suche schon seit Stunden in der API Dokumentation....

Gruß,
Holger

19.02.2013 - 12:07 Uhr

Hallo,
wir werden in naher Zukunft im Unternehmen in naher Zukunft von VS2010 auf VS2012 updaten. Der TFS bleibt vorerst die 2010er Version.

Jedes Tool-Update muss bei uns durch einen Verifikationsprozess und ich muss den Aufwand der Verifikation abschätzen. Daher folgende Fragen:

  • Laufen die TFS PowerTools 2010 mit VS2012 ? Oder muss auf PowerTools 2012 geupdated werden ?
  • Sind in der Kombi TFS 2010 und VS2012 eMail-Alerts nutzbar ?

Gruß,
Holger alias impact

08.08.2011 - 12:43 Uhr

Hallo,
ich habe einen eigenen WebService geschrieben, der vom TFS über geänderte WorkItems informiert wird (WorkItemChangedEvent).

Angemeldet habe ich den Webservice am TFS über eine GUI-Version des TFS-Kommandozeilentools "bissubscribe.exe" und meinem eigenen Account.

Hier meine Frage:
Was passiert, wenn mein Passwort abläuft, oder mein Account gesperrt wird? Ist die Subscription dennoch gültig ?

Gruß,
Impact

10.05.2011 - 15:12 Uhr

Hallo,

wie kann ich per C# und VS/TFS API ein WorkItem mit gegebener ID im WorkItem-Fenster öffnen ?
Brauche nur ein die grobe Vorgehensweise 😃

Gruß,
Holger

30.03.2011 - 12:01 Uhr

Hallo,

ich weiß, dass man eigene WorkItem-Types in ein bestehendes TeamProjekt importieren kann.
Aber:

  • kann man Areas / Iterations eines laufenden TeamProjektes (bzw. des darunterliegenden Prozesses) ändern ?
  • kann man WorkItem-Types eines laufenden TeamProjektes löschen ? Was passiert dann mit den WorkItems der gelöschten Typen ?

Gruß,
Impact

30.03.2011 - 11:55 Uhr

Hi,

es gibt die TFS PowerTools, die eine Integration in den Windows-Explorer bieten, dann muß VS nicht mehr extra gestartet werden.

Außerdem gibt es SVNBridge, damit kann man TortoiseSVN usw. verwenden. SVNBridge scheint allerdings nicht richtig zu funktionieren (zumindest bei mir).

Gruß,
Holger alias impact

01.02.2011 - 16:15 Uhr

@Xynatron: Testlisten möchte ich vermeiden, da ich dann aufgrund unterschiedlicher Pfade zwei unterschiedliche Listen verwalten muß: einmal für die Developer und einmal extra für den Build.

@JAck30lena:
Build-Workflows gehen nur mit TFS2010....

Man kann den "/Testcontainer:<.dll>" Kommandozeilenparameter mehrfach angeben. Das möchte ich automatisiert für alle Einträge einer File-Liste machen (über eine ItemGroup).

Verstanden was ich meine ?

Das Buildscript soll also automatisch für alle .dlls in einem Verzeichnis einen "/TestContainer:<.dll>" Parameter erstellen !

27.01.2011 - 12:18 Uhr

Früher gab es hier eine regere Beteiligung..... Oder liegt es am Thema ?

Jedenfalls verwende ich jetzt den Exec-Task um MSTest.exe aufzurufen.

Nun würde ich MSTest.exe über multiple commandline-parameter "/TestContainer:myassembly.dll" die Liste der zu testenden dlls übergeben.

Die zu testenden dlls befinden sich in einer ItemGroup:

<ItemGroup>
<TestContainers Include="$(MyBinariesDir)*.dll"/>"
</ItemGroup>

Mal angenommen, es sind 2 dlls enthalten. Wie bekomme ich es hin, dass MSTest.exe mit folgenden Optionen gestartet wird:

"MSTest.exe /TestContainer:erste.dll /TestContainer:zweite.dll"

Versteht ihr, was ich meine ?

19.01.2011 - 14:54 Uhr

Kann mir keiner helfen ?
Muß ich TestToolsTask nutzen, oder reicht der Exec-Taks ?

17.01.2011 - 14:49 Uhr

Hallo, ich habe folgende Konfiguration:

  • TeamBuild 2008 Installation, auf dem Build Rechner sind VS2008 und VS2010 Professional installert
  • VS2010 Clients
  • VS2010 Projekte
  • Team Build 2008 ist so configuriert, dass MSBuild 4.0 genutzt wird

Die Projekt-Assemblies enthalten MS Unit-Tests, die während des TeamBuilds ausgeführt werden sollen. Failed Tests sollen einen failed Build mit eMail-Benachrichtigung nach sich ziehen.

Wenn ich nun im BuildScript <RunTest>true</RunTest> setze, bekomme ich die Fehlermeldung, dass meine VS2010 Version das nicht zulässt (nur verfügbar in der Ultimate-Edition). Als Ausweg möchte ich MSTest.exe zum Ausführen der Tests verwenden, was testweise in der VS-Kommandozeile auch funktioniert.

Aber wie muß das Build-Skript aussehen, damit bei "roten" Tests der Build gebrochen und eine entsprechende eMail versendet wird ?

Gruß,
Impact79

03.01.2011 - 17:39 Uhr

Hallo,
ich habe hier ein TFS 2008 TeamBuild, in welches ich FXCop (mit fxcop-projektdatei) integrieren soll. Momentan bin ich etwas verwirrt:

Kann ich fxcopcmd.exe direkt in das MSBuild-Projekt einbinden, oder brauche ich das MSBuild Extension Pack dazu ?

Gruß,
Impact

12.11.2010 - 16:10 Uhr

Das habe ich auch gelesen. Erklärt aber nicht wieso bei einer Machine mit 2 Kernen 600 (!) auftreten kann...

12.11.2010 - 12:39 Uhr

Hallo,
der Titel sagt fast schon alles.

Mein System:
Core 2 Duo, 2 phyiskalische Kerne, kein HT. Environment.ProcessorCount ergibt erwartungsgemäß 2.

Ich würde also bei folgendem Code Werte bis maximal 200 erwarten:


var cpuusage = new PerformanceCounter("Process", "% Processor Time", "meinprozess").NextValue();

Ich bekomme aber teilweise Werte bis 600 !
Wie ist das möglich ?

Gruß,
Impact

05.11.2010 - 10:48 Uhr

Doch, habe viel gefunden und viel probiert. Nur nichts was funktioniert hat.....
Aber der zweite Link sieht tatsächlich sehr vielversprechend aus (keine Ahnung wieso der nicht auf meinem Radar war), Danke dafür !

04.11.2010 - 17:59 Uhr

Klar wäre das einfacher und sauberer, aber genau das möchte ich in diesem Fall nicht.

Aber sind MessageHeader und Extensions nicht auch dazu gedacht ? Ich meine in der MSDN gelesen zu haben, dass man damit bspw. Statusinformationen übertragen kann....

Wie setzte ich im Client MessageHeader oder Extensions, so dass ich sie am Server auslesen kann ? Oder ist das prinzipiell nicht möglich ? MessageProperties z.b werden nicht übertragen... (in einem Blog gelesen)

04.11.2010 - 16:30 Uhr

Hallo,

ich möchte auf WCF-Client Seite mittels OperationContext der aktuellen Nachricht zusätzliche Informationen "mitgeben", die der Server dann wieder extrahieren kann.

Ziel ist es nicht den bestehenden Contract so zu ändern, das ich dort die gewünschten Infos schicken kann !

Verdächtige Kandidaten wären:

  • OperationContext.Current.Extensions
  • OperationContext.Current.OutgoingMessageHeaders

Leider erreichen dort hinzugefügte Infos nicht den Server....

Gruß,
Impact

03.11.2010 - 20:27 Uhr

Hi, Problem ist mittlerweile gelöst. Wichtig ist wohl, dass in der app.config die echte IP des Rechners angegeben wird, und nicht localhost oder 127.0.0.1

Aber danke für Deine Antwort ! 😃

03.11.2010 - 17:57 Uhr

Hallo,
habe hier ein Client und ein Server - Programm. Der Server stellt einen WCF-Service bereit, den der Client über WCF-Service-Discovery findet. Wenn sowohl Client- als auch Server-App auf dem gleichen Rechner laufen, klappt alles.

Sobald aber Client und Server auf verschiedenen Rechnern am gleichen Router laufen, wird der WCF-Service nicht mehr vom Client gefunden.....

Hat jemand eine Idee ??

Gruß,
Impact

26.10.2010 - 12:10 Uhr

Hallo Leute,

ich habe einen Server, der mittels BinaryFormatter Objekte serialisiert und dann in sehr kurzen Intervallen wiederholt an N verschiedene Clients schickt. Dort werden die Objekte wieder deserialisiert.

Sowohl auf Client als auch auf Server-Seite nutze ich einen TCPClient und schreibe / lese in/von dessen NetworkStream.

Meine Objekte sind bis zu 104000 Bytes groß. Die BufferSize des Arrays zum Lesen aus dem Stream ist 1048576 (1MB groß).

Frage: Die BufferSize zum Lesen / Schreiben kann auch an den TCPClients gesetzt werden.


            //  setzen der BufferSize am TcpClient. ist das nötig ?
            mTcpClient.SendBufferSize = MySocket.BUFFERSIZE;
            mTcpClient.ReceiveBufferSize = MySocket.BUFFERSIZE;
            (...:)
            // setzen der größe des readbuffers. wie verhält sich das zur buffersize am tcpclient ?
            mReceiveBuffer = new byte[MySocket.BUFFERSIZE];
            var networkStream = mTcpClient.GetStream();
            networkStream.BeginRead(mReceiveBuffer, 0, mReceiveBuffer.Length, new AsyncCallback(BeginReadCallback), networkStream );

Ich nehme an die Send/ ReceiveBufferSize am TCPClient muß immer mindestens so groß sein wie die Größe des Arrays zum lesen der Daten ? Ist das richtig ?

Dennoch sind immer mal wieder die Buffer augenscheinlich korrupt, da der BinaryFormatter von Zeit zu Zeit die Objekte nicht serialisieren kann.....

Woran könnte das liegen ?

Gruß,
Impact

28.09.2010 - 11:57 Uhr

Hallo,
wenn ich einen WCF-Service über die ServiceHost-Klasse hoste und 10 Endpoints bereitstelle, kann ich dann bei einem gerade stattfindenden Service Aufruf herausfinden welcher der 10 Endpoints verwendet wurde (siehe Code)?


    // service contract interface
    [ServiceContract]    
    public interface IPCL
    {
        [OperationContract]
        void A(int position);
    }
    // service implementation
    public class PCLService : IPCL 
    {
         public void A(int position)
         {
                // wenn der debugger hier steht
                // wie kann ich dann den genutzten Endpoint herausfinden ?
         }
      }

Gruß,
Impact

23.09.2010 - 18:39 Uhr

Sorry, muß ich genauer erklären:

  1. Ich benutze OpenVPN um vom HomeOffice auf das Netzwerk meiner Firma zuzugreifen. In diesem Falle funktioniert eMail und Internetzugriff wird meines wissens NICHT über die Firma geroutet.

  2. Zusätzlich muß ich mich von Zeit zu Zeit mittels der Nortel-VPN in das Netzwerk eines Kunden einloggen. In diesem Fall geht eMail nicht, und der Internetzugriff wird durch den Filter des Kundennetzwerks begrenzt.

BEIDE VPNs nutzen einen eigenen, virtuellen Netzwerkadapter. Allerdings routet OpenVPN - wenn ich das richtig verstanden habe - nur Anfragen an das Firmennetz darüber. Mein Internetzugriff und eMails laufen weiterhin direkt über meine physikalische Netzwerkkarte.

Bei der Nortel VPN wird aber wohl alles über die virtuelle Karte geschickt.

Nun möchte ich, dass sich die Nortel-VPN wie OpenVPN verhält und nur Zugriff auf das Firmennetz ( = in diesem Falle das Intranet des Kunden) über die virtuelle Netzwerkkarte routet.

Hoffe ich habe das halbwegs richtig zusammengefasst....

23.09.2010 - 16:58 Uhr

Hmm.
Wieso ist das dann bei OpenVPN, Hamachi etc. möglich ? Soweit ich weiß wird dort nicht der komplette Internetverkehr über die VPN geroutet, oder doch ?

Meine VPNs:
OpenVPN zur eigenen Firma.
Nortel VPN zum Kunden.

23.09.2010 - 15:57 Uhr

Hallo,
ich arbeite im HomeOffice und verbinde mich über eine VPN mit meiner Firma um zu entwickeln. Leider funktioniert dann eMail nicht mehr, und jeglicher Internetverkehr wird über die VPN geroutet !
Viele Seiten sind verboten. D.h ich muß mich jedes mal von der VPN abmelden, um bspw. eMails abrufen zu können... Das nervt !

Gibt es eine bequeme Möglichkeit / ein Tool mit dem ich eMails / Internet an der VPN vorbei über eine andere Netzwerkkarte routen kann ?

Gruß,
Holger

15.07.2010 - 17:37 Uhr

So hab ich es gemacht (Danke für den Tipp) und folgendes herausgefunden:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
muß in der Assembly angegeben werden, von welcher aus der erste Aufruf nach LogManager.GetLogger() erfolgt !

Das das nirgends in der log4net doku steht..... kopfschüttel
(oder hab ich es überlesen?)

15.07.2010 - 16:44 Uhr

Hallo,

gibt es eine Möglichkeit Im TFS 2010 einen Bericht zu erstellen, der die LOC (Lines of Code) zwischen verschiedenen Builds anzeigt ? Am besten aufgeschlüsselt nach geändert / gelöscht / hinzugefügt....

Gruß,
Impact

14.07.2010 - 17:37 Uhr

Keiner ne Idee ?

13.07.2010 - 19:52 Uhr

Hallo,

ich habe VS2010 und VS2008 parallel installiert und benutze log4net zum Loggen.

Zur Konfiguration von log4net benutze ich folgendes Statement in AssemblyInfo.cs


[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Eigentlich ist also alles Standard.

Komischerweise funktioniert das Konfigurieren auf diese Art aber nur, wenn ich die Applikation im Release-Mode ohne Debugging (strg + f5) starte !

Möchte ich die Applikation mit debugging starten, brauche ich folgendes Statment als ersten Befehl in Program.cs, damit Logging trotzdem funktioniert:


XMLConfigurator.Configure()

Witzig daran ist, dass DANN (aber nur dann) AUCH die Konfiguration per AssemblyInfo.cs ausgeführt wird. Hier die Ausgabe, die das belegt:

log4net: XmlConfigurator: configuring repository [log4net-default-repository] using file [D:.....exe.Config] watching for file updates
log4net: XmlConfigurator: configuring repository [log4net-default-repository] using file [D:.....exe.Config]

Kann sich da jemand einen Reim draus machen ?

Gruß,
impact

17.05.2010 - 18:33 Uhr

verwendetes Datenbanksystem: MSSQL, Oracle

Hallo,
ich muß eine Datenbank von MS SQL Server 2005 nach Oracle 10g Express "umziehen".

Bisher habe ich eine Migration über den Oracle SQL-Developer probiert, was beim konvertieren der Tabellenschemas fehlschlägt (ohne detaillierte Fehlerbeschreibung). Außerdem habe ich versucht die DB-Skripte von T-SQL nach PL/SQL automatisiert übersetzen zu lassen. Das funktioniert aber auch nicht, da der SQL-Developer nur die Basis-Statements übersetzen kann.

Frage: Kann ich da nicht einen Umweg über C# nehmen ? Quasi typisiertes DataSet automatisiert aus SQL-Server abrufen und dann programmatisch in Oracle einspielen ? Oder gibt es evtl. die Möglichkeit das DB-Schema als XML abzuspeichern und dann in Oracle zu importieren ?

Gruß,
Impact

11.05.2010 - 12:17 Uhr

Hallo,

habe in meinem DGV das Pasten von Daten ins Clipboard implementiert. Das Kopieren über STRG+C ist ja standardmäßig implementiert, da habe ich bisher keine Hand angelegt.

Hier mein Problem. Wenn ich das ganze DGV selektiere und dann per STRG+C kopiere, wird für jede RowHeader-Zelle ein leerer Wert übernommen.
Das möchte ich verhindern. Gibt es dafür einen einfachen Weg (z.b ein property das ich übersehen habe), oder muß ich dafür tatsächlich die Kopierfunktion selbst implementieren ?

Gruß,
Impact

16.04.2010 - 11:17 Uhr

Beeindruckender Artikel! Allerdings habe ich nicht alles verstanden.

Du beschränkst Dich darauf, Exceptions aus dem nebenläufigen Thread folgendermaßen zu fangen, damit sie nicht verloren gehen. Ist das richtig ?

     
 [STAThread]
      static void Main() {
         (...)
         AppDomain.CurrentDomain.UnhandledException += SideThread_Exception;
         (...)
      }

      static void SideThread_Exception(object sender, UnhandledExceptionEventArgs e) {
         MessageBox.Show("Log unhandled side-thread-Exception here\n" + e.ExceptionObject.ToString());
         Application.Exit();
      }


Unabhängig davon, ist folgender Code sinnvoll ? So dürften auch keine Exceptions verloren gehen und ich belaste den Post-Mechanismus nicht...


        /// <summary>
        /// perform an operation (parameter asyncAction) in a background thread, then execute a callback (paremter afterAsync) 
        /// when the operation finished. Execute an other operation (exceptionAction parameter) when an exception occurs (exceptionAction will be executed in background-thread, so be careful when modifying controls).
        /// </summary>
        /// <param name="asyncAction">operation to be executed in background thread</param>
        /// <param name="afterAsync">operation to be executed when background thread finishes</param>
        /// <param name="exceptionAction">operation to be executed when an exception occurs</param>
        public static void PerformInBackgroundThread(Action asyncAction, SendOrPostCallback afterAsync, ExceptionDelegate exceptionAction)
        {
            Action actionWrapper = delegate
            {
                try
                {
                    asyncAction();
                }
                catch (Exception ex)
                {
                    exceptionAction(ex);
                }
            };

            actionWrapper.BeginInvoke(delegate(IAsyncResult result)
            {
                UIThreadContext.Post(afterAsync, null);
                actionWrapper.EndInvoke(result);
            }, null);
        }

15.04.2010 - 18:23 Uhr

Was haltet ihr hiervon: Eine Klasse mit statischen Methoden zum einfachen "delegieren" von Operationen an einen Background-Thread:

        
  public class BackgroundThreadLauncher
    {
        public static SynchronizationContext UIThreadContext
        {
            get;
            set;
        }
        /// <summary>
        /// perform an operation (parameter asyncAction) in a background thread, then execute a callback (paremter afterAsync) 
        /// when the operation finished. Execute an other operation (exceptionAction parameter) when an exception occurs (thread exists in this case).
        /// </summary>
        /// <param name="asyncAction">operation to be executed in background thread</param>
        /// <param name="afterAsync">operation to be executed when background thread finishes</param>
        /// <param name="exceptionAction">operation to be executed when an exception occurs</param>
        public static void PerformInBackgroundThread(Action asyncAction, SendOrPostCallback afterAsync, SendOrPostCallback exceptionAction)
        {
            asyncAction.BeginInvoke(delegate(IAsyncResult result)
            {
                try
                {
                    UIThreadContext.Post(afterAsync, null);
                    asyncAction.EndInvoke(result);
                }
                catch (Exception ex) {                    
                    UIThreadContext.Post(exceptionAction, ex);
                    return;
                }
            }, null);
        }


        /// <summary>
        /// perform an operation (parameter asyncAction) in a background thread, then execute a callback (paremter afterAsync) 
        /// when the operation finished. this overloaded version of the method just outputs exceptions to the console
        /// </summary>
        /// <param name="asyncAction">operation to be executed in background thread</param>
        /// <param name="afterAsync">operation to be executed when background thread finishes</param>     
        public static void PerformInBackgroundThread(Action asyncAction, SendOrPostCallback afterAsync)
        {
            PerformInBackgroundThread(asyncAction, afterAsync, delegate(object state) {
                Console.WriteLine("An Exception has been thrown in BackGroundThreadLauncher.PerformInBackGroundThread: " + ((Exception)state).ToString());
            });
        }
    }
}



Ein Aufruf sieht dann so aus:


 BackgroundThreadLauncher.PerformInBackgroundThread(delegate
                {
                    // work for background thread
                }, delegate(object state)
                {
                    // work to be done when thread ends
                }, delegate(object state) {
                   // code to be executed when an exception occurs
                });  

Ein Problem gibt es noch: Wenn eine Exception auftritt, dann öffnet sich - ohne das ich etwas dagegen tun kann - zusätzlich eine kleine, leere MessageBox mit OK-Button und Fehler-Icon (aber ohne Text). Ich nehme an das das irgendwie vom WindowsSynchronisation-Context geöffnet wird. Wie kann ich das verhindern ?

Oder wie sieht eurer Meinung nach ein passenderes Exception-Handling aus ?

15.04.2010 - 16:37 Uhr

Problem gelöst. Könnte auch für andere von Interesse sein.
Wenn AutoSizeColumnMode auf "AllCells" gesetzt ist, geht CellValueNeeded direkt nach dem setzen von RowCount über alle Zellen in allen Zeilen.

Das heißt für alle die ähnliche Probleme haben: Mal mit AutoSizeColumnMode spielen !

Hier habe ich die Lösung gefunden (letzter Beitrag):
Microsoft Forum

15.04.2010 - 13:34 Uhr

Hallo,
ich habe ein DGV im virtual Mode. Nachdem ich RowCount setze, wird der Handler für CellValueNeeded für jede Zelle in jeder Zeile abgerufen ! Bei meinen knapp 52000 Zeilen macht das 2 Mio Aufrufe was dazu führt, das die App solange "einfriert".

Sollte CellValueNeeded nicht nur für die sichtbaren Zeilen aufgerufen werden ?

Gruß,
Impact

07.04.2010 - 17:25 Uhr

Ok, ich entferne das Using()...

@ErfinderDesRades:
Sieht sehr interessant aus, allerdings blicke ich noch nicht ganz durch. Wieso wird in Deinem Beispiel der asyncAction-Code im Hintergrundthread ausgeführt ? Erzeugt die BeginInvoke() Methode automatisch einen Hintergrundthread ?

PS:
Funktioniert übrigens wunderbar !

06.04.2010 - 20:02 Uhr

Jetzt bin ich etwas verunsichert:
Auf den ersten Blick hast Du Recht, allerdings funktioniert der Code ! Beide Delegaten werden ausgeführt !

Vielleicht hat die Garbage-Collection die Objekte noch nicht gelöscht.... Oder gibt es eine andere Erklärung ?

06.04.2010 - 19:27 Uhr

Hallo !

Spricht etwas dagegen BackgroundWorker folgendermaßen zu nutzen ? Finde das relativ übersichtlich....


        private void PerformMiscBusinessLogicInBackgroundThread() {
            using (BackgroundWorker worker = new BackgroundWorker()) {
                worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args)
                {
                    // logik die ausgeführt werden soll wenn der thread endet
                };
                worker.DoWork += delegate(object sender, DoWorkEventArgs args) {
                  // logik des threads
                };
                worker.RunWorkerAsync();
            }
        }

Ich nehme an, dass durch das using() - Statement alles sauber aufgeräumt wird. Ist das richtig ?

Gruß,
Impact

26.03.2010 - 10:19 Uhr

Hat keine ne Idee ?
Oder liegt es an der Formulierung der Frage ?

25.03.2010 - 10:43 Uhr

verwendetes Datenbanksystem: <Sql Server 2005>

Hallo,
ich möchte den Typ DataColumn erweitern und habe dafür eine davon abgeleitete Klasse "MyDataColumn" erstellt, welche zusätzliche Properties enthält. Die neuen Properties sollen im DataSet-Designer visuell editierbar sein.

Wie bekomme ich den DataSetDesigner dazu, die zusätzlichen Properties anzuzeigen ?

Ich habe versucht in DataSet.Designer.cs den Typ der Columns der DataTables manuell von DataColumn in MyDataColumn zu ändern. Das klappt allerdings nicht, weil die Änderung jedes mal wenn ich den Designer benutze wieder überschrieben wird.

Ein anderer Ansatz wäre es, eine MyDataTable-Klasse (die von DataTable) ableitet zu erstellen, die MyDataColumns enthält.

Aber wie bekomme ich dann wiederum Instanzen der MyDataTable-Klasse zum visuellen Editieren in den DataSet-Designer ?

Gruß,
Impact

11.03.2010 - 20:31 Uhr

Stimmt, da hatte ich wohl Tomaten auf den Augen. Das ist aber nicht das prinzipielle Problem !

Selbst wenn ich im Debugger manuell true oder false setze, kommt später die Exception.

Habe ich denn von der Idee her (OnCellFormatting() überschreiben) alles richtig gemacht ?

11.03.2010 - 18:17 Uhr

Hallo !
Komplizierter Titel, hier nochmal genauer.

Wir haben eine DataTable mit einer Value-Spalte. Diese Value-Spalte enthält Strings, die sich aus Y und N zusammensetzen. Für jedes Zeichen des Strings soll eine CheckBoxColumn im DataGridView angezeigt werden. Dabei bedeuted Y = CheckBox gechecked, und N = CheckBox nicht gechecked.

Ein Beispiel:
YNNY bedeutet -> 4 CheckBox-Spalten in DataGrid, für diese Zeile sind die erste und die letzte Checkbox-Spalte "angehakt".

Das soll ich nun umsetzen. Ich weiß, das ist kein gutes DB-Design, aber ich kann daran nichts ändern und muß erstmal mit dieser Vorgabe leben.

Als Lösungsansatz habe ich eine von DataGridView abgeleitete Klasse erstellt und dort die OnCellParsing und OnCellFormatting - Methoden überschrieben.

Hier mein Code zum Erstellen der CheckboxColumns (mit DataBinding an die "Value" Spalte, die die "NN" Strings enthält:

 
...
                 var cbColumn = new DataGridViewCheckBoxColumn();
                //cbColumn.TrueValue = "Y";
                //cbColumn.FalseValue = "N";
                cbColumn.DataPropertyName = mDataTable.Columns["Value"].ColumnName;
                if (i == 0)
                {
                    cbColumn.DisplayIndex = 0;
                }
                CheckBoxColumns.Add(cbColumn);
                this.Columns.Add(cbColumn);
...

Hier mein Code für OnCellFormatting():


        protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e)
        {
                // falls checkbox column (könnte man auch anders prüfen)
                var dc = CheckBoxColumns.FirstOrDefault(c => c.Index == e.ColumnIndex);
                if (dc != null)
                {
                    // nr der checkboxcolumn in der checkboxcolumncollection ist die position des zugeordneten Zeichens in der Value Spalte
                    var index = CheckBoxColumns.IndexOf(dc);
                    // konvertiere das zeichen an der richtigen position in einen wert, den die column darstellen kann
                    // Beispiel: vorher NN, jetzt false ! 
                    e.Value = this["Value", e.RowIndex].Value.ToString()[index] == 'Y' ? true : false;
                    // formattierung erledigt
                    e.FormattingApplied = true;
                }
        }

Das funktioniert leider nicht ! Es wird sinngemäß folgende Exception geworfen: "Kann "NN" nicht in boolean konvertieren"

Weiß jemand was ich falsch mache ?

Gruß,
Impact

10.03.2010 - 16:27 Uhr

@FZelle:
Das ist in meinem Fall nicht möglich, das DGV wird gefordert !

@all
Habe das Problem mittlerweile gelöst. Hier grob die Vorgehensweise

  1. Dafür sorgen, daß BindingNavigator nicht selbst eine neue Zeile erzeugt, durch setzen der BindingNavigator.AddNewItem - Eigenschaft im VS-Designer auf (none).
  2. ClickHandler für den +-Button des BindingNavigators schreiben
  3. dort manuell eine neue Zeile der BindingSource des DGV anlegen, siehe folgenden Code. Das Geheimnis liegt darin, das die neue Row nach dem anlegen erstmal NICHT an das darunterliegende DataTable commited wird. Sondern beim nächsten Click auf den + - Button und im OnFormClosing() event. Für das manuelle commit reicht meines Wissens Form.Validate().
 
        /// <summary>
        /// add new rows manually 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnAddNewItem(object sender, EventArgs e)
        {
            // validieren der form, dadurch werden m.W früher angelegte rows in die datenquelle geschrieben
            if (this.Validate())
            {
                if (bnDataTable.BindingSource != null)
                {
                    // neue zeile in der bindingsource anlegen
                    bnDataTable.BindingSource.AddNew();
                    // neu angelegte zeile ist aktuelle zeile !
                    var currentrow = dgvEditTable.CurrentRow;
                    // optional setzen einiger / aller default werte
                    foreach (string key in mColumnDefaultValues.Keys)
                    {
                        if (dgvEditTable.Columns.Contains(key))
                        {
                            currentrow.Cells[key].Value = mColumnDefaultValues[key];
                        }
                    }
                }
            }
        }

  1. DataError-Event des DGV handeln, event canceln (siehe Code unten)

        /// <summary>
        /// handle data errors
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnDataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            MessageBox.Show("Please enter values in all marked rows !");
            e.Cancel = true;
        }

Mir ist noch nicht klar warum durch diese Lösung das DataError-Event gefeuert wird. Das war vorher nicht der Fall ! Vielleicht kann jemand Licht ins Dunkel bringen...

Gruß,
Impact

10.03.2010 - 09:26 Uhr

Kannst Du das bitte näher erläutern ?
Wie kann ich im DGV etwas editieren, wenn ich "Enable Editing" auf false setze ?

09.03.2010 - 18:50 Uhr

Hallo,

ich habe genau das gleiche Problem, gleiches Szenario, gleiche Controls ! Habe alle Beiträge zu diesem Thema gelesen und den ganzen Arbeitstag mit der Suche der Lösung verbracht. Leider bisher kein Erfolg....

Falls es für dieses Problem tatsächlich keine Lösung gibt: Wie setzt man folgende Anforderung richtig um ?

  1. eine Form zur Editierung von verschiedenen DataTables, bestehend aus DGV mit DataSource = DataTable und BindingNavigator
  2. auf einigen Spalten der DataTables "sitzt" ein Constraint, der DBNull verbietet
  3. die Spalten, die nicht DBNull sein dürfen, sind im Grid bereits farblich markiert
  4. der User vergisst dennoch, in diese Spalte einen Wert einzutragen
    5. Anforderung: Zeige nun eine MessageBox, die den User auffordert in alle markierten Spalten einen Wert einzutragen.

Wie kann man diese Anforderung umsetzen ?

Gruß,
Impact

05.03.2010 - 15:40 Uhr

Danke, hat funktioniert !

Allerdings frage ich mich warum es nicht im OnLoad() - klappt....

05.03.2010 - 12:48 Uhr

Hallo !

Ich habe ein DataGridView mit ButtonColumns. Im OnLoad() - EventHandler der Form setze ich den Text der Buttons individuell durch (Achtung, Pseudocode)

((DataGridViewButtonCell)dgv[rowindex,buttoncolumnindex]).Value = "MeinText"

Leider funktioniert das nicht, der Button bleibt leer ! Die Button-Cell hat - wenn die Form fertig geladen ist - plötzlich einen Index von -1 !

Verschiebe ich das ganze beispielsweise in den OnMouseMove() - EventHandler, dann klappts !

Weiß jemand Rat ?

Gruß,
Impact

04.03.2010 - 18:19 Uhr

Das war genau was ich wissen wollte, Danke !