Going to move my blog? (ziehe ich ziehe um?)

MAYBE this will be my last entry on this blog. I’m going to move. The new blog URL:

http://dotnet-forum.de/blogs/rainerhilmer/default.aspx

Vielleicht wird das der letzte Beitrag in diesem Blog sein. Ich ziehe um. Die neue Blog-Adresse:

http://dotnet-forum.de/blogs/rainerhilmer/default.aspx

DotNetKicks-DE Image

Kategorien:Allgemein

Brain degeneration process unstoppable?

Watch this video of a nuclear explosion and read the comments.

http://www.youtube.com/watch?v=H1sS1TmXF38&feature=related

It’s just 20 years ago when everybody was still shocked by the view of a nuclear explosion – but here and now all I can see is stupid comments! 20 years ago we thought the end of mankind would be world war III where everything is nuked. Now I fear the end of mankind will be due to the loss of  brain power.

Kategorien:News and politics

AntiFor patterns

I have read Matthew Podwysocki’s AntiFor campaign article recently and I wondered wether it is possible to substitute all kinds of for-loops with LINQ expressions.
This came back to my mind when I wrote a little application yesterday which consists of some for-loops.
Here are the three methods with for-loops and their counterparts which use LINQ, so you can compare them directly.

using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace AntiForVersuche
{
   public class AntiFor
   {
      //======================================================================
 
      // Spaltet einen multiline-Text in einzelne Zeilen und setzt diese in ein String-Array.
      public string[] SplitText2LinesWithFor(string text)
      {
         char[] splitCharacters = { 'n' };
         var lines = text.Split(splitCharacters);
         for(var i = 0; i < lines.Length; i++)
         {
            lines[i] = lines[i].TrimEnd('r');
         }
         return lines;
      }
 
      public IEnumerable<string> SplitText2LinesWithLinq(string text)
      {
         char[] splitCharacters = { 'n' };
         if(text == null)
            return null;
         string[] lines = text.Split(splitCharacters);
         var query = lines.Select(value => value.TrimEnd('r'));
         return query;
      }
 
      //======================================================================
 
      // Setzt drei Slashes vor jede Zeile.
      public string[] PrependXmlCommentSignsWithFor(string[] lines)
      {
         var result = new string[lines.Length];
         for(int i = 0; i < lines.Length; i++)
         {
            result[i] = "///" + lines[i];
         }
         return result;
      }
      
      public IEnumerable<string> PrependXmlCommentSignsWithLinq(IEnumerable<string> lines)
      {
         if(lines == null)
            return null;
         if(lines.Count() == 0)
            return null;
         var query = lines.Select(value => "///" + value);
         return query;
      }
 
      //======================================================================

 

// Fügt die einzelnen Zeilen wieder zu einem Multiline-Text zusammen.

      public string ConcatenateLinesWithFor(string[] lines)
      {
         var builder = new StringBuilder();
         for(int i = 0; i < lines.Length; i++)
         {
            builder.AppendLine(lines[i]);
         }
         return builder.ToString();
      }
 
      public string ConcatenateLinesWithLinq(IEnumerable<string> lines)
      {
         if(lines == null)
            return null;
         if(lines.Count() == 0)
            return null;
         string query = lines.Aggregate((build, line) => build + "rn" + line);
         query += "rn";
         return query;
      }
   }
}

Conclusion


Well, these three samples sure don’t answer my initial question to my utter satisfaction but they showed me some of the possibilities and I’m confident. It has been a pretty informative piece of work for me because I never used the Select and Aggregate Extension methods before. Maybe this blog post is as informative for some of you out there as it has been for me.

Kategorien:C# allgemein

Software-Eigenmächtigkeiten

Nicht nur daß die Installation von Windows Live Essentials meine IE-Startseite geändert hat, ohne mich zu fragen GRRRRRRR!!!!!!! >:-(

nein, dieses Miststück von Messenger startet sich jedesmal bei dem Besuch einer Webseite, die irgendwas mit Windows live zu tun hat (wie z.B. mein Blog) von selber – obwohl ich in den Optionen eingestellt habe daß er das nicht soll!!!
Ich schmeiß diesen Dreck in die Tonne!!!!!!!!

Hat jemand ‘ne Gif-Animation die das Messenger-Icon erschießt?

Kategorien:Sonstiges

NUnit, a competitor for MS-Test, which you shouldn’t let pass by without a closer look!

I hesitated a long time. I use MS-Test, PEX and CHESS. Shouldn’t that be enough? Why the heck another unit test framework? Reading “The Curse of the Rewrite” from Tim Ross got me curious today (and most of all after I saw the code, wich uses NUnit). That blog post deals with testing of legacy code – but that’s just a side note.
So what’s special about NUnit? Well, just look at this line of code:

Assert.That(documentManager, Is.InstanceOfType(typeof(DocumentManager)), "Should create an instance of DocumentManager");

It’s code which fulfills the BDD paradigm at last! So I downloaded and installed NUnit, looked at the syntax sample and I’m convinced ever since.
If you have never heard of NUnit or still hesitate as I did before, than just take a look at this syntax sample. It’s right from the installation. I hope they don’t sue me for this. It’s pure advertising (but an honest one ;-) ).

// ****************************************************************
// Copyright 2007, Charlie Poole
// This is free software licensed under the NUnit license. You may
// obtain a copy of the license at http://nunit.org/?p=license&r=2.4
// ****************************************************************
 
 
// Cropped due to text length constraints in this blog. :-/
// ...
// The original code is much longer!
 
      [Test]
      public void IsTrue()
      {
         // Classic syntax
         Assert.IsTrue(2+2==4);
 
         // Helper syntax
         Assert.That(2+2==4, Is.True);
         Assert.That(2+2==4);
 
         // Inherited syntax
         Expect(2+2==4, True);
         Expect(2+2==4);
      }
 
      [Test]
      public void IsFalse()
      {
         // Classic syntax
         Assert.IsFalse(2+2==5);
 
         // Helper syntax
         Assert.That(2+2== 5, Is.False);
         
         // Inherited syntax
         Expect(2+2==5, False);
      }
 
// Cropped due to text length constraints in this blog. :-/
// ...
// The original code is much longer!
      
      [Test]
      public void CollectionContainsTests()
      {
         int[] iarray = new int[] { 1, 2, 3 };
         string[] sarray = new string[] { "a", "b", "c" };
 
         // Classic syntax
         Assert.Contains(3, iarray);
         Assert.Contains("b", sarray);
         //...
 
         // Helper syntax
         Assert.That(iarray, Has.Member(3));
         Assert.That(sarray, Has.Member("b"));
         Assert.That(sarray, Has.No.Member("x"));
         //...
      
         // Inherited syntax
         Expect(iarray, Contains(3));
         Expect(sarray, Contains("b"));
         Expect(sarray, Not.Contains("x"));
 
         //...
      }
 
      // ...
 
      [Test]
      public void SubsetTests()
      {
         int[] ints1to5 = new int[] { 1, 2, 3, 4, 5 };
 
         // Classic syntax
         CollectionAssert.IsSubsetOf(new int[] { 1, 3, 5 }, ints1to5);
         CollectionAssert.IsSubsetOf(new int[] { 1, 2, 3, 4, 5 }, ints1to5);
         CollectionAssert.IsNotSubsetOf(new int[] { 2, 4, 6 }, ints1to5);
         CollectionAssert.IsNotSubsetOf(new int[] { 1, 2, 2, 2, 5 }, ints1to5);
 
         // Helper syntax
         Assert.That(new int[] { 1, 3, 5 }, Is.SubsetOf(ints1to5));
         Assert.That(new int[] { 1, 2, 3, 4, 5 }, Is.SubsetOf(ints1to5));
         Assert.That(new int[] { 2, 4, 6 }, Is.Not.SubsetOf(ints1to5));
      
         // Inherited syntax
         Expect(new int[] { 1, 3, 5 }, SubsetOf(ints1to5));
         Expect(new int[] { 1, 2, 3, 4, 5 }, SubsetOf(ints1to5));
         Expect(new int[] { 2, 4, 6 }, Not.SubsetOf(ints1to5));
      }
      #endregion
 
      #region Property Tests
      [Test]
      public void PropertyTests()
      {
         string[] array = { "abc", "bca", "xyz", "qrs" };
         string[] array2 = { "a", "ab", "abc" };
         ArrayList list = new ArrayList( array );
 
         // Not available using the classic syntax
 
         // Helper syntax
         Assert.That( list, Has.Property( "Count" ) );
         Assert.That( list, Has.No.Property( "Length" ) );
 
         // ...

Do you know any other unit test framework which can beat this? Let me know!

Kategorien:Allgemein

Sample code in help files, namespace descriptions and angle brackets in XML comments. How to get around these hurdles.

3. August 2009 1 Kommentar

This tutorial will show you how to add sample code into your custom help files. It will not show you how to make help files in general because you can find several tutorials for this in the internet. Just one tip:
Get Sandcastle from Microsoft at
http://www.microsoft.com/downloads/details.aspx?familyid=E82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en

and the Sandcastle help file builder from codeplex.
http://www.codeplex.com/SHFB

You can also find a “Getting started” section in the Sandcastle help file builder documentation. 

Now let’s go:
At first you must enable XML documentation file in the build section of the project properties.

image

Writing the sample code
To add sample code, you have to write (and test!) it first, of course.

using System;
 
namespace XmlCommentSampleCodeDemo
{
   class DemoCode
   {
      // This is the demo code which will be inserted into the XML-comment of the AddWorldTo-method.
      public void Demo()
      {
         MyClass instance = new MyClass();
         string myString = "Hello";
         string result = instance.AddWorldTo(myString);
         Console.WriteLine(result);
      }
   }
}

A demo class with inserted sample code
Just copy and paste the demo code into the XML-comment block as shown below. Notice that the code is surrounded by a <code>-Section which is contained in an <example>-section.

namespace XmlCommentSampleCodeDemo
{
   /// <summary>
   /// This class is just a sample for the XML documentaion.
   /// You will see this line at the class level in the help file.
   /// </summary>
   public class MyClass
   {
      /// <summary>
      /// Adds " world." to a string.
      /// </summary>
      /// <param name="someString">Any string.</param>
      /// <returns>A modificated string.</returns>
      /// <example>
      /// <code>
      /// public void Demo()
      /// {
      ///    MyClass instance = new MyClass();
      ///    string myString = "Hello";
      ///    string result = instance.AddWorldTo(myString);
      ///    Console.WriteLine(result);
      /// }
      /// </code>
      /// </example>
      public string AddWorldTo(string someString)
      {
         return someString + " world.";
      }
   }
}

 

The help entry
After generating the helpfile with Sandcastle help file builder, the entry for the AddWorldTo method will look like this:

image

Namespace comments
Namespace comments are special because you cannot comment a namespace by default. Hopefully this will change with a future release of Visual Studio. Meanwhile you need the following trick to achieve this goal.

namespace XmlCommentSampleCodeDemo
{
   // Add this empty class in conjunction with this attribute to your project.
 
   /// <summary>
   /// This is just an entry to demonstrate a namespace comment.
   /// </summary>
   [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   class NamespaceDoc
   {
   }
}

Here you can see the comment for the namespace in the help.

image 

How to get angle brackets in a code example
When you have angle brackets the compiler will warn you about inappropriate tags. This is simply because either the XML file with the comments as the code inside the comments use them together. To overcome this problem you have to surround the code with a <![CDATA[ ]]> tag.
Here is an example:

/// <summary>
      /// My method.
      /// </summary>
      /// <param name="stringList">The string list.</param>
      /// <example>
      /// <code>
      /// <![CDATA[
      /// // This is no usage example.
      /// public void MyMethod(List<string> stringList)
      /// {
      ///   //...
      /// }
      /// ]]>
      /// </code>
      /// </example>
      public void MyMethod(List<string> stringList)
      {
         //...
      }

This is what it looks like in the help.
image

Note: You could also use HTML-tags for the angle brackets but

  1. it looks distracting and
  2. it’s likeley to forget or overlook them here and there. With the compilation time of the help file in mind, it’s very annoying when that happens.
Kategorien:Allgemein

Parallel file search, Part 4

Hier noch ein paar Unit Tests. Darunter auch ein Concurrency-Test mittels CHESS.

/**********************************************************************************************
 * In order to make these tests working correctly, they must run in MTA and not STA as usual. *
 * This modification is done in the LocalTestRun.testrunconfig with the                       * 
 * <ExecutionThread apartmentState="MTA" /> -tag.                                             *
 **********************************************************************************************/

using System;
using System.IO;
using Cyrons.ParallelSearch;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;

namespace ParallelSearchTests
{
   /// <summary>
   ///This is a test class for ParallelFileSearcher and is intended
   ///to contain all ParallelFileSearcher Unit Tests.
   ///</summary>
   [TestClass]
   public class ParallelFileSearcherTest
   {
      private static int eventCounter;

      /// <summary>
      ///Gets or sets the test context which provides
      ///information about and functionality for the current test run.
      ///</summary>
      public TestContext TestContext { get; set; }
      
      /// <summary>
      ///A test for GroupDriveItems
      ///</summary>
      [TestMethod]
      [DeploymentItem("ParallelSearch.dll")]
      public void ShouldCreate3FolderGroups()
      {
         var folders = new List<SearchSet>();
         var searchSet = new SearchSet(
            new DirectoryInfo(@"A:"), SearchOption.TopDirectoryOnly);
         folders.Add(searchSet);
         searchSet = new SearchSet(
            new DirectoryInfo(@"B:"), SearchOption.TopDirectoryOnly);
         folders.Add(searchSet);
         searchSet = new SearchSet(
            new DirectoryInfo(@"C:"), SearchOption.TopDirectoryOnly);
         folders.Add(searchSet);
         /* A fourth entry is for a logical drive that's already in the list.
          * So even we have 4 entries, we should get 3 folder groups only. */
         searchSet = new SearchSet(
            new DirectoryInfo(@"C:Program files"), SearchOption.TopDirectoryOnly);
         folders.Add(searchSet);

         IEnumerable<IGrouping<string, SearchSet>> actual
            = ParallelFileSearcher_Accessor.GroupDriveItems(folders);
         Assert.AreEqual(3, actual.Count());
      }

      [TestMethod]
      [HostType("Chess")]
      [TestProperty("ChessBreak", "BeforePreemption")]
      [TestProperty("ChessDebug", "true")]
      [Ignore] // Ran 2000 Threads without problems. Test has been aborted after that to save time.
      public void ChessParallelTest()
      {
         // See the remark at the top of the code.
         Console.WriteLine("Current thread state (should be MTA!): "
            + System.Threading.Thread.CurrentThread.GetApartmentState().ToString());
         const bool ignoreExceptions = true;
         var fileContentSearcher = new ParallelFileSearcher(ignoreExceptions);
         fileContentSearcher.FoundFile += NewFileFoundHandler;
         var searchSets = new List<SearchSet>();
         
         searchSets.Add(new SearchSet(
            new DirectoryInfo(@"C:Program Files"),
            SearchOption.TopDirectoryOnly));
        
         searchSets.Add(
            new SearchSet(
            new DirectoryInfo(@"H:VS2008LabCyronsFramework"),
            SearchOption.AllDirectories));
         
         searchSets.Add(
            new SearchSet(
            new DirectoryInfo(@"I:DeveloperVS2008ProjectsDemosEigeneCallBackDelegateEssential"),
            SearchOption.AllDirectories));

         Console.WriteLine("Bitte warten. Dateien werden gesucht...");

         // Define search-parameters.
         const string filenamePattern = "*.cs";
         const string contentToSearchFor = ""; // Could also be null.

         // Start the search with those parameters.
         List<FileInfo> fileInfos =
            fileContentSearcher.FindFiles(
            searchSets, filenamePattern, contentToSearchFor, FindMode.FindAll);
         // Do something with fileInfos like, for instance, delete those files.
         Console.WriteLine(fileInfos.Count);
      }

      [TestMethod]
      public void ShouldGetCallOutEvent()
      {
         // Siehe Anmerkung.
         Console.WriteLine("Current thread state (should be MTA!): "
            + System.Threading.Thread.CurrentThread.GetApartmentState().ToString());
         // Create a search-list.
         var searchList = new List<SearchSet>();

         // Generate Search sets...
         var searchSet = new SearchSet(
            new DirectoryInfo(@"H:VS2008LabActiveRecordPattern"),
            SearchOption.AllDirectories);
         // ...and add them to the search-list.
         searchList.Add(searchSet);

         searchSet = new SearchSet(
            new DirectoryInfo(@"I:DeveloperVS2008ProjectsDemosEigeneCallBackDelegateEssential"),
            SearchOption.AllDirectories);
         searchList.Add(searchSet);

         searchSet = new SearchSet(
            new DirectoryInfo(@"C:Program Files"),
            SearchOption.TopDirectoryOnly);
         searchList.Add(searchSet);

         const bool ignoreExceptions = true;
         const string filenamePattern = "*.cs";
         const string contentToSearchFor = null;
         var parallelFileSearcher = new ParallelFileSearcher(ignoreExceptions);
         parallelFileSearcher.CallOutUnauthorizedAccess += ShowCurrentlyDeniedAccess;
         parallelFileSearcher.FoundFile += NewFileFoundHandler;
         List<FileInfo> files = parallelFileSearcher.FindFiles(
            searchList,
            filenamePattern,
            contentToSearchFor,
            FindMode.FindAll);
         Assert.IsTrue(eventCounter > 0);
      }

      [TestMethod]
      public void ShouldNotFailOnDeniedAccess()
      {
         var searchList = new List<SearchSet>();
         // The bad guy.
         var searchSet = new SearchSet(
            new DirectoryInfo(@"C:System Volume Information"), SearchOption.TopDirectoryOnly);
         searchList.Add(searchSet);
         const bool ignoreExceptions = true;
         const string filenamePattern = "*.*";
         const string contentToSearchFor = null;
         var parallelFileSearcher = new ParallelFileSearcher(ignoreExceptions);
         parallelFileSearcher.CallOutUnauthorizedAccess += ShowCurrentlyDeniedAccess;
         parallelFileSearcher.FoundFile += NewFileFoundHandler;
         List<FileInfo> files = parallelFileSearcher.FindFiles(
            searchList,
            filenamePattern,
            contentToSearchFor,
            FindMode.FindAll);
         Assert.IsTrue(eventCounter > 0);
      }

      [TestMethod]
      public void ShouldNotFailOnInvalidPath()
      {
         var searchList = new List<SearchSet>();
         // The bad guy.
         var searchSet = new SearchSet(new DirectoryInfo(@"X:"), SearchOption.AllDirectories);
         searchList.Add(searchSet);
         const bool ignoreExceptions = true;
         const string filenamePattern = "*.cs";
         const string contentToSearchFor = null;
         var parallelFileSearcher = new ParallelFileSearcher(ignoreExceptions);
         parallelFileSearcher.CallOutUnauthorizedAccess += ShowCurrentlyDeniedAccess;
         parallelFileSearcher.FoundFile += NewFileFoundHandler;
         List<FileInfo> files = parallelFileSearcher.FindFiles(
            searchList,
            filenamePattern,
            contentToSearchFor,
            FindMode.FindAll);
         Assert.IsTrue(files.Count == 0);
      }

      #region Helpers

      private static void ShowCurrentlyDeniedAccess(string fullName)
      {
         Console.WriteLine("Access denied for " + fullName);
         eventCounter++;
      }

      private static void NewFileFoundHandler(string fullFileName)
      {
         Console.WriteLine("found " + fullFileName);
      }

      #endregion
   }
}

Kategorien:Allgemein
Follow

Erhalte jeden neuen Beitrag in deinen Posteingang.