Wednesday, November 04, 2009

.NET4 is too good to be true

Lately I played around the Parallel extensions in .NET 4 and I was almost impressed that it was better than expected :-)
--> In the initial example we did use Thread.Sleep inside the loops, so our speed up gain for going parallel was more than 4x …  :-)

Pre-requisites

  • I run this on VS2010 in a VPC with single CPU and around 1.5GB of RAM
  • There is no Disk IO or network IO involved in the benchmark
  • We have a long running process called DoCalc were we tested different algorithms from the port of the SciMark 2.0 Benchmark to C#
    The original benchmark was in Java and can be found at http://math.nist.gov/scimark2
  • I used the code from the “measureSOR” method, because
    • It takes the same time on each run (stable between consecutive runs)
    • It is the fastest one of all the calculation examples
  • The “measureSOR” method is a port of the SciMark2a Java Benchmark to C# by Chris Re (cmr28@cornell.edu ) and Werner Vogels (vogels@cs.cornell.edu )
    Thanks for that!

Code

See the following example (I removed all Debug output and Stopwatch code)

            for (int i = 0; i < 5; i++)
            {
                DoCalc();
            }

And the same code with the Parallel extensions

            Parallel.For(0, 5, i =>
            {
                DoCalc();
            });

The DoCalc is just a wrapper around measureSOR, because of easy replacing and testing

        private static void DoCalc()
        {
            var res = PerformCalculationMeasureSOR();
        }

        private static double PerformCalculationMeasureSOR()
        {
            SciMark2.Random R = new SciMark2.Random(SciMark2.Constants.RANDOM_SEED);
            var res = SciMark2.kernel.measureSOR(SciMark2.Constants.SOR_SIZE, SciMark2.Constants.RESOLUTION_DEFAULT, R);
            return res;
        }

When we run these 2 methods we get

Output

Output from running in a for loop
Calculation process started at 26/08/2009 12:45:28 PM
Starting process 0
Run: 0   Result: 404.89
Completed process 0 took 5.4336615 seconds

Starting process 1
Run: 1   Result: 404.89
Completed process 1 took 4.7462174 seconds

Starting process 2
Run: 2   Result: 407.99
Completed process 2 took 4.7405446 seconds

Starting process 3
Run: 3   Result: 402.85
Completed process 3 took 4.7832635 seconds

Starting process 4
Run: 4   Result: 408.33
Completed process 4 took 4.7051044 seconds

Calculation finished at 26/08/2009 12:45:52 PM and took 24.418825
Hit <Enter>

Output from running parallel

Calculation process started at 26/08/2009 12:43:07 PM
Non-parallelized for loop
Starting process 0
Starting process 1
Starting process 2
Starting process 3
Starting process 4
Run: 2   Result: 68.17
Completed process 2 took 5.9277232 seconds

Run: 1   Result: 90.60
Completed process 1 took 9.0088243 seconds   // take longer because overlapping

Run: 0   Result: 90.45
Completed process 0 took 9.0282256 seconds   // take longer because overlapping

Run: 3   Result: 84.78
Completed process 3 took 5.2585445 seconds

Run: 4   Result: 192.39
Completed process 4 took 6.3435232 seconds

Calculation finished at 26/08/2009 12:43:20 PM and took 13.2818383
Hit <Enter>

 

Interesting notes here

  • In the NON parallel loop, each method call takes ~same amount of time
  • In the parallelized loop those methods that overlap, take longer (9 secs)
  • The parallel run in not 4x faster than the iterative run! (as it was with Thread.Sleep :-)
  • We almost halved the execution time as expected
    BUT sometimes the execution time is faster than half the time (around 10 seconds) image
     
  • Additionally if we run the parallel for loop 10 times we just need another 17 seconds...
    For an explanation we could have a deeper look at the algorithm behind SOR
    Jacobi Successive Over-relaxation (SOR) http://math.nist.gov/scimark2/about.html

clip_image002
Figure: Running the parallel for  10times takes only ~ 17 seconds

 

With the help of Paul we were able to figure out what is going on here…

Findings

Our findings running in the VPC image:

  • If we run the "normal" for loop, the CPU doesn't go crazy (only around 88%-98% of usage)
  • If we run the parallel loop , the CPU usage is much higher (~100%)

Our findings running on bare metal (real dual core CPU)

clip_image001
Figure 1.  Linear vs Parallel CPU utilization for loops

Conclusion

#1 CPU usage (=performance) is slightly scheduler dependent

I am not a OS expert but I guess the above means: “Windows sees more threads, and gives them more time on the CPU”

#2 Using the Parallel extensions is VERY EASY! Looking forward to the final release!

Thursday, October 29, 2009

Sometimes it works, sometimes not

This is not good!
If something in your software is dependent from the combination of

  1. current weather in London (weather there changes very often, and you and your system actually sits in Sydney)
  2. the mood of your girlfriend (or wife) this morning and
  3. amount of nuts in your muesli in your breakfast bowl

you have a big problem

 

I can’t run tests anymore with MsTest
“Sometimes I can”
... and I am not sure if this is the fault of the latest TFS KB Update... Since we moved to TFS2010 we had to install this KB to work with VS2008 an TFS2010

When I try to run my tests I get this error

clip_image002

Same problem as Gabriel had described in his post about Error: "Exception has been thrown by the target of an invocation."
His solution: none. Over time it was fine :-)

To reproduce this I can easily do

  1. Start VS2008
  2. Go to “Test” | “Windows” | “Test Results”
  3. Error message!

image

I had a couple of things installed like: Resharper, Testdriven.Net, Coderush, … and was not sure what it is…
The last thing I installed was the KB article about using VS2008 with TFS2010.

What I did and didn’t help:

  • Start up Visual Studio in safe mode (parameter /SafeMode )
  • Start up Visual Studio and reset user data (parameter /resetuserdata )

---------------------------------
Note: I hate to do a /resetuserdata because it looses all my “nice” settings like:

  • Removing animations and speedup start of VS
  • Changing F1 keyboard key to do NOTHING (That’s a big one!) ( -> Tools -> Options –> Environment –> Keyboard –> F1 “Remove” )
  • Track Active Item in Solution Explorer ( -> Tools -> Options -> Projects and Solutions  )

More of this settings can be found on stackoverflow Visual Studio optimizations
---------------------------------

 

After all that, I attached another VS to the other one running with “Debug” –> “Attach to process” and enabling all exceptions in “Debug” –> “Exceptions”

---------------------------------
Note: I saw a lot of Resharper exceptions once I start to open a solution and browsing through files…
exceptions in VSActionManager.cs, VSProjectInfo.cs, VSSolutionManager.cs, …
---------------------------------

BUT NO EXCEPTION when I tried to reproduce the problem!
image 
Figure: The top VS2008 is attached to the lower one (that reproduces the error).

Fix: None so far
but I was able to run the tests (and to see my “Test results” window) sometimes.

I think it must be a weird combination of “devenv /safemode”, “Open solution”, “Build”, “Clean”, “Rebuild”, “Cross fingers”, “Run all tests”… Or maybe the other combination mentioned at the top of the post.
Didn’t figure it out yet

Will update this post once I know!

Monday, October 19, 2009

Tools that I use and that are not on Scott Hanselman’s list of tools

I did a new install of Win7 RC last Saturday morning (my quickest install ever with my new SSD HD!!) During the install I wrote down the tools that I installed. I realised some of them are not on Scott Hanselman’s tools list! But almost all are mentioned in the comments on his blog post

This is the list of tools that I always install
And these are NOT on Scott’s tool list

Total Commander
File manager - the german “swiss army knife”. The best tool ever! Replaces Windows File Explorer, Winzip, Winrar, Beyond compare, FTP tools, …and more!

Fullshot
Screenshot utility - Don’t really like SnagIt, because its harder to use

Stroke It - Don’t be just a keyboard jed
Mouse gesture to the max - I used Symbol Commander, Sensiva in the past, but Stroke It is free

Stardock Fences
Organizes my desktop, and double-click  hide icons is great for presentations

SharpReader
My blog reader of choice, I know its old and they didn’t release a version since a couple of months / years …. but it just works

Shortkeys
Text replacement - I got used to that one and have 20 short cuts in there, don’t want to migrate to autohotkey…. to painful

Browser Selector
Depending on the URL that I click on emails it opens different browser, great! and other features described in this blog post about Browser Selector

Free Download Manager
1. Save all downloads in 1 place (FireFox, IE, …) 2. Resume downloads and 3. free

WinPatrol
Like “autorun” from sysinternals but keeps my system healthy in the background. If there is a change in my system –> Warning

irfanview
My picture viewer of choice. fast and shows all file extensions in the world

SSMS Tools
Enhances SQL Management Studio with features like: Create INSERT INTO script for table …

Nmap
If you don’t know it you don’t need it

mRemote
Save all your RDP, SSH, VNC connections in 1 place and connect by double click

 

Scott uses different tools and that is good.

My comments

What I found strange that there is no mouse gestures tool. I think he is a keyboard master and is not using a mouse at all probably :-) Or he is using some authotkey script for mouse gestures…

There is no file manager in Scott’s list. Just FAR file manager (DOS, crazy!!)  :-(

Friday, October 16, 2009

Firefox as default browser and IE for SharePoint

If you are using more than 1 browser in your daily work life, make sure to use the small little “Browser Selector” tool from Marco

The good thing for me is:

  • Firefox is my default browser (web apps like gmail, wave, … just work nicer)
  • Opera is for reading (reading, zooming, 100 open tabs: Opera is still FAST)
  • IE is for Microsoft sites like SharePoint, MS CRM, … (that require IE or Kerberos authentication)

My configuration looks like this

<?xml version="1.0" encoding="utf-8" ?>
<BrowserSelector>
  <Rules>
    <Rule Url="microsoft.com" Browser="IE" />
    <Rule Url="msdn.com" Browser="IE" />
    <Rule Url="msn.com" Browser="IE" />
    <Rule Url="live.com" Browser="IE" />
    <Rule Url="sharepoint.ssw.com.au" Browser="IE" />
    <Rule Url="crm.ssw.com.au" Browser="IE" />
    <Rule Url="intranet.ssw.com.au" Browser="IE" />
-------SNIP SNIP SNIP SNIP -------
  </Rules>
  <Browsers>
    <Browser Name="Firefox" Path="C:\Program Files (x86)\Mozilla Firefox\firefox.exe" Default="true" />
    <Browser Name="Opera" Path="C:\Program Files (x86)\Opera\opera.exe" />
    <Browser Name="IE" Path="C:\Program Files (x86)\Internet Explorer\iexplore.exe" />
  </Browsers>
</BrowserSelector>

Get it from the dedicated “Browser selector” project page

Friday, September 11, 2009

VB.NET Aaaarrrrggghhh - The missing return statement doesn’t give a compile error

Today I found another reason why i don’t like VB.NET

I forgot (commented out) the Return statement in a function (see below) to test different LINQ operators.
During running and later debugging my application I got strange LINQ runtime errors (1 result set is Nothing) …

   Public Function PerformSearch(ByVal dc As myDataContext, _
                                  ByVal searchString As String, _
                                  ByVal memberId As Long) _
                    As IQueryable(Of SearchResult)

        searchString = GetFulltextSearchString(searchString)
       
        Dim q = From fulltextSearch In _
       '  -- SNIP SNIP -- removed LINQ code for blog

        ' Return q
    End Function

Figure: VB.NET function without a return statement

 

After a while I realized that the function doesn’t return nothing! But NO COMPILE ERROR! WTF???

image
Figure: BAD: No compile error

The compiler says: Warning “Function ‘PerformSearch’ doesn’t return a value on all code paths. A null reference exception could occur at run time when result is used.”

I realized that myself after a while :-| 

 

image  
Figure: BAD: Visual Studio shows me a curly line underneath “End Function” – but then I have to mouse hover to actually see the problem

 

The weird thing is, that this is by convention (from MSDN) : If the function/procedure doesn’t assign a value to the function-name AND doesn’t use the “Return” statement the function returns the default value of the return type (=Nothing (null) in my case…)  :-(

My recommendations:

  • Always use the “Return” statement in VB.NET (when I don’t forget it ;-) ) instead of assigning a value to the “procedure name” and having “Exit Function”. Its just easier to read!
  • And to make the execution flow more easier to read, I prefer a “return” statement as last line of a method/function/procedure

See this BAD example

    Public Function CalcMyValue(ByVal x As Integer, ByVal y As Integer) As Integer

        Dim returnValue As Integer
        If (x > 100 And y > 365) Then
            Return 1
        Else
            If (x > 100 And y > 365) Then
                returnValue = x * 1000
            Else
                Return -1
            End If
        End If
        returnValue = returnValue * 7
        Return returnValue

    End Function

Figure: Bad example with mix of return statements in the middle 

Note
There is a Visual Studio option per Visual Basic project, to set the “compile warning” to a “compile error”
List with all warnings in VB on MSDN

image
Figure: Why is this an option? and why is the default a “Warning”?? WTF

Thursday, September 03, 2009

What is --- End of inner exception stack trace ---

Why is my Stack trace split into 2 half's, delimited by “End of inner exception stack trace “??

Example StackTrace from one of my older applications, that manages GPS points

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionHandlingException: The type 'Old.Base.DataAccess.ExceptionHandler.OracleExceptionHandler, Old.DataAccess, Version=2.0.0.11969, Culture=neutral, PublicKeyToken=null' cannot be resolved. Please verify the spelling is correct or that the full type name is provided. ---> System.ArgumentException: The type 'Old.Base.DataAccess.ExceptionHandler.OracleExceptionHandler, Old.DataAccess, Version=2.0.0.11969, Culture=neutral, PublicKeyToken=null' cannot be resolved. Please verify the spelling is correct or that the full type name is provided.
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.AssemblyQualifiedTypeNameConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at System.ComponentModel.TypeConverter.ConvertFrom(Object value)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.NameTypeConfigurationElement.get_Type()
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.CustomProviderAssembler`3.Assemble(IBuilderContext context, TConfiguration objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.AssemblerBasedObjectFactory`2.Create(IBuilderContext context, TConfiguration objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyEntryCustomFactory.Create(IBuilderContext context, ExceptionTypeData objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource)
   at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.LocatorNameTypeFactoryBase`1.Create(String name)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.GetExceptionPolicy(Exception exception, String policyName, ExceptionPolicyFactory factory)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.GetExceptionPolicy(Exception exception, String policyName, ExceptionPolicyFactory factory)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName)
   at Old.SLFD.PlanManager.DataAccess.OracleODP.ImageSaverDAO.InsertImage(InsertImageParameter imageParam)
   at Old.SLFD.PlanManager.BusinessLogic.ImageManipulationBL.ImportImages(String elencoPtFilename, String imagefolder)
   at Old.SLFD.PlanManager.WinForms.Controls.CreationAndImportImages.StartImport()
   at Old.SLFD.PlanManager.WinForms.Controls.CreationAndImportImages.toolbarsManager_ToolClick_1(Object sender, ToolClickEventArgs e)
   at Infragistics.Win.UltraWinToolbars.ToolClickEventHandler.Invoke(Object sender, ToolClickEventArgs e)
   at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.OnToolClick(ToolClickEventArgs e)
   at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.FireEvent(ToolbarEventIds id, EventArgs e)
   at Infragistics.Win.UltraWinToolbars.ToolBase.OnToolClick()
   at Infragistics.Win.UltraWinToolbars.ButtonToolUIElement.DoClickProcessing(MouseEventArgs e)
   at Infragistics.Win.UltraWinToolbars.ButtonToolUIElement.OnMouseUp(MouseEventArgs e)
   at Infragistics.Win.ControlUIElementBase.ProcessMouseUpHelper(Object sender, MouseEventArgs e)
   at Infragistics.Win.ControlUIElementBase.ProcessMouseUp(Object sender, MouseEventArgs e)
   at Infragistics.Win.Utilities.ProcessEvent(Control control, ProcessEvent eventToProcess, EventArgs e)
   at Infragistics.Win.UltraControlBase.OnMouseUp(MouseEventArgs e)
   at Infragistics.Win.UltraWinToolbars.UltraToolbarsDockArea.OnMouseUp(MouseEventArgs e)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Figure: ArgumentException in my code.

Long time ago, I was wondering why?

The obvious reason for this, is that an Exception can hold an InnerException (see property in screenshot).

image
Figure: Reflector showing type: Exception


This happens if the exception is caught by some other code in the middle (e.g. Business layer; see difference between layers and tiers with nice pictures and nice list of pro/contra ) and wrapped in a new exception.

In the example above EnterpriseLibrary catches an exception and wraps it into another exception. Enterprise Library has an Exception Handling Application Block that lets you configure policies for your exceptions.
E.g. Handle “SQLException” globally, log and email the exception, then wrap it into “MyCustomException” depending of the property “SqlException.Errors”
That is something similar we did for System.Data.OracleClient.OracleException

Tuesday, August 18, 2009

Check for a feature and not a version

The most important thing I learned from a presentation of Andrew Coates on Windows development was

If you use a specific feature of a Windows OS, check for that specific feature and not for the Windows OS version!

 

E.g. You create an awesome application that uses the new Windows 7 taskbar features!

bad BAD: DON’T determine the windows OS version and react on that (enable/disable functionality), but test the API for the feature!
DON’T use code mentioned in this blog post: “Determine Windows Version and Edition with C#” or more complicated here: C# Detect Windows OS Version


good GOOD: Use the API provided from Microsoft for Windows 7 : Windows API Code Pack

Add this namespace

using Microsoft.WindowsAPICodePack.Taskbar;

Verify this property on the class TaskbarManager

TaskbarManager.IsPlatformSupported

 

PS
In this blog post you can found how you use the progress bar of the Windows 7 taskbar

Thursday, July 30, 2009

Code smell - READIBILITY

In my opinion readability is the most important attribute of code.

Good code should be easy to read.
That makes code easy to understand, maintain and REUSE.

 

Ignore the meaning of the code but look at the layout... What would you prefer?

  if (myTrueValue) myFirstTempVariable = 1;
  if (!myTestStatement) mySecondTempVariable = 0;
  if (mySecondTestStatement) myThirdTempVariable = 0;
  if (!myFourthTestStatement) mySecondTempVariable = 1;
Hard to read

 

  if (myTrueValue == true) myFirstTempVariable = 1;
  if (myTestStatement == false) mySecondTempVariable = 0;
  if (mySecondTestStatement == true) myThirdTempVariable = 0;
  if (myFourthTestStatement == false) mySecondTempVariable = 1;
GOOD: Already much easier to read

 

  if (true == myTrueValue) myFirstTempVariable = 1;
  if (false == myTestStatement) mySecondTempVariable = 0;
  if (true == mySecondTestStatement) myThirdTempVariable = 0;
  if (false == myFourthTestStatement) mySecondTempVariable = 1;
GOOD: What about this? Already much easier to read??

Thursday, June 04, 2009

Instead of displaying x item(s) found

from today on we use the following code

Console.WriteLine("{0} item{1} found.", count, count==1 ? "" : "s");

and get a nice output like

201 items found 

instead of

201 item(s) found 

 

From stackoverflow
http://stackoverflow.com/questions/9033/hidden-features-of-c/821718#821718

Saturday, May 23, 2009

How to create a Karaoke machine in Silverlight

(Scroll to the bottom for the nice UI)

clip_image002
Figure: Karaoke machine UI done by a Developer :-)

Goal

  1. We have 2 textboxes for artist and title
  2. On click of “Start fun” button we call a web service to get the lyrics of the requested song
  3. After that we scroll the lyrics in the textbox below

See how easy that is, with Silverlight!!!

System overview

clip_image002[4]
Figure: Silverlight application calls the local web server, which calls the Lyrics web server

It’s that complicated, because cross domain access is blocked in Silverlight and the Lyrics web service doesn’t have a clientaccesspolicy.xml file

 

Prerequisites

“Silverlight SDK Toolkit”

Download “Silverlight SDK Toolkit” from MSDN
http://www.microsoft.com/downloads/details.aspx?FamilyId=c22d6a7b-546f-4407-8ef6-d60c8ee221ed&displaylang=en

Create a new Silverlight Application project

clip_image004
Figure: Create a Silverlight project

clip_image006
Figure: Yes, Add a ASP.NET web project

Create a reference to the external Lyrics web service

  1. Right click on “SilverlightApplication.Web”
    clip_image008
  2. Click on “Add Web Reference”
  3. Use this URL to reference the web service
    http://lyricwiki.org/server.php?wsdl
  4. Click on Add Reference to finish
    clip_image010

Create the web service proxy that calls the external Lyrics web service

  1. Right click on “SilverlightApplication.Web”
  2. Add New item
    clip_image012
  3. Choose “Web Service”
  4. Name it “LyricService”
  5. Enter a new method called GetSong
[WebMethod]
public org.lyricwiki.LyricsResult GetSong(string artist, string title)
{
    org.lyricwiki.LyricWiki lyricWiki = new org.lyricwiki.LyricWiki();
    return lyricWiki.getSong(artist, title);
}

Build your solution!

Create a reference to the web application proxy service



Create the layout (page.xaml)

<UserControl x:Class="SilverlightApplication.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <StackPanel>
        <TextBlock  Text="Artist"></TextBlock>
        <TextBox x:Name="textBoxArtist" Width="200" Margin="5" Height="50"></TextBox>
        <TextBlock  x:Name="Artist" Text="Title"></TextBlock>
        <TextBox x:Name="textBoxTitle" Width="200" Margin="5" Height="50"></TextBox>
        <Button x:Name="buttonStart" Content="Start fun!" Margin="10" Width="100" Height="50" Click="buttonStart_Click"></Button>
        <TextBlock x:Name="textBlockResult" FontSize="20"  Text="nothing so far" Margin="10" Height="30" Width="700"></TextBlock>
    </StackPanel>
</UserControl>
Figure: XAML for the ugly Karaoke player

Code! Finally :-)


Use a timer to tick every 100 milliseconds and scroll through the lyrics

DispatcherTimer timer = new DispatcherTimer();  
timer.Interval = new TimeSpan(0, 0, 0, 0, 100);  
timer.Tick += new EventHandler(timer_Tick);

On each timer tick, we scroll the text


private void ScrollText()
{
// Scroll 1 caret to the left, I know thats not nice :-) but easy!
textBlockResult.Text = textBlockResult.Text.Substring(1) + textBlockResult.Text.Substring(0, 1);
}

Create the event handler on song completed call

    //No code, tooo easy

Create the timer and start it after song completed call

    //No code, tooo easy

 

 

Remember: Everything is async in Silverlight



Advanced Tasks


1. Add a slider for the speed of the text

clip_image018


Figure: Slider for adjusting the speed of the text scrolling


2. Make your Silverlight application look pretty

clip_image020


3. Make the text show only 1 line full, the other lines with low opacity

Google for: Silverlight Opacity


4. Scroll the text line by line (instead by characters)

Search for the first Newline in the text and split the text there


5. Make the application go in full screen after start

Have a look at http://www.silverlightshow.net/tips/Tip-How-to-enter-full-screen-mode.aspx


6. If no title entered, let the user choose from a list of songs by the artist

clip_image022


7. Make the song scroll like Star wars

See http://franksworld.com/blog/archive/2009/05/01/11451.aspx

clip_image024


8. Embed a youtube video next to the text of that song

See http://code.google.com/apis/youtube/overview.html for details on calling the youtube webservice

Wednesday, May 20, 2009

Please: Rowtests in Visual Studio 2010?

I hope that we can finally do row tests ([RowTest] attribute) in Visual Studio 2010, like we can in mbUnit and nUnit.
That would make our data driven unit tests so much easier!!!

But nothing to find on the official VS2010 webpage or Soma’s Blog Search for Rowtest

 

[TestMethod]
[DeploymentItem(@"TestData\validConditions.txt")]
[DeploymentItem(@"TestData\schema.ini")]
[DataSource("System.Data.OleDb", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|;Extended Properties='text;FMT=TabDelimited;HDR=YES'", @"validConditions#txt", DataAccessMethod.Sequential)]
public void ValidateRulesEntry_Valid_ValidConditionsFromFile()
{
	string condition = TestContext.DataRow[0].ToString();
	string returnMessage;


	bool successFul = CodeParserTryParseCondition(condition, "No error", out returnMessage);


	Assert.IsTrue(successFul, string.Format("Condition: {0}. Error: {1}.", condition, returnMessage));
}
BAD: Input data is in a text file, to view that data I have to open the text file

 

[TestMethod]
[RowTest]
[Row("Target.IsDirty")]
[Row("Target.IsValid")]
[Row("Target.Description.Contains(""Test"")")]
[Row("(1 != 2)")]
public void ValidateRulesEntry_Valid_ValidConditionsFromFile()
{
	string condition = TestContext.DataRow[0].ToString();
	string returnMessage;


	bool successFul = CodeParserTryParseCondition(condition, "No error", out returnMessage);


	Assert.IsTrue(successFul, string.Format("Condition: {0}. Error: {1}.", condition, returnMessage));
}
GOOD: Input data for unit test is attached to unit test itself --> easy to read, understand!

Thursday, May 14, 2009

Getting the current Twitter-buzz with C#

My problem
I want to know what my friends on Twitter are talking about most

image

What’s the plan:

  1. Get the tweets from my friends
  2. Search this tweets for the #hashtags (Regex!!!)
  3. Count the hashtags
  4. Output the hashtags ordered by count

With tools like VS, .net framework and Twitter API this is EASY!!
Wooohooo

1. How to get the tweets

a) Twitter API

Find all info here http://apiwiki.twitter.com/ 
Currently Twitter has 2 APIs, maybe they make things easier and bring these together…
image

b) Tweetsharp

Tweetsharp is an awesome fluent interface for the Twitter API.
It’s toooo easy!!!! Make sure you check it out

http://code.google.com/p/tweetsharp/
image

c) Twitter "low level"

You can consume Twitter stuff via standard HTTP calls and get the response as XML or JSON, see this blog for an example http://psantos-blog.zi-yu.com/?p=197
That’s tooo hard :-)

 

I picked Tweetsharp, because there are so many samples available, and it is fluent!  I love Intellisense!

  1. Download tweetsharp http://code.google.com/p/tweetsharp/
  2. Unzip to your References Solution folder
  3. Add reference to your project
  4. Done

How easy is that!

 

Note
Make sure to use a Console project, we want to focus on functionality not on UI
image

 

The code to get the list of tweets looks like this

           var twitter = FluentTwitter.CreateRequest().AuthenticateAs(MyUser, MyPass) 
           .Statuses().OnFriendsTimeline().Take(1000).AsJson();

           // Get response from Twitter
           var response = twitter.Request();

           // Convert response to data classes
           var tweets = response.AsStatuses();

 

Next step

Iterate through tweets and search for the hashtags
We use a Regex for that

private static Regex regexHashTags = new Regex(@"#\w*", RegexOptions.IgnoreCase);

No more code, because that’s up to you how to do that

 

Put this hashtags into dictionary

Dictionary<string, int> 

(string is the hashtag, int is the count)
Easy, so no code here

 

Sort the Dictionary with LINQ

var sortedDict = (from entry in hashtagCountDict orderby entry.Value descending select entry);

 

The final output is easy again

Iterate through the sorted dictionary and throw it to the Console

image
Figure: Output of current Twitter buzz. Sharepoint is big currently (13/05/2009)
because of the TechEd announcements of Sharepoint 2010

 

Advanced steps

  1. Get the tweet updates every couple of seconds
  2. Use a   while (abortKeyNotPressed) {   }  with a Thread.Sleep to get the buzz every 1 minute
  3. Use Console KeyAvailable to abort application
  4. Use the space key to get the current state of the iteration
  5. Serialize current dictionary to file, and load that at startup
    Continue from last time

 

Thanks Robert Mühsig for VERY useful input http://code-inside.de/blog/2009/04/20/howto-twittern-mit-c/

Monday, May 04, 2009

How to: Take my ASP.NET 2.0 web app offline

Bad
After 4 years, (just today) I found a nice feature in ASP.NET from the year 2005!

Upload a file called “App_Offline.htm” to your web application root, to bring the whole application offline!
How easy is that!

Good
I never had to take one of my web applications offline
:-)

From Erik Porter (year 2005!!!)
http://weblogs.asp.net/eporter/archive/2005/10/05/426708.aspx

Monday, April 06, 2009

Internet Explorer 8: Little things that matter

Try to guess which Tab page is the current one

image
Figure: IE 8

 


image
Figure: Chrome 1.0

 


image
Figure: Opera 9.5

 


image
Figure: Firefox 3

Friday, March 13, 2009

Troubles with XQuery in SQL server

My daily problems with XML, XQuery in SQL Server 2005.

We save XML in a VARCHAR column.

Why not VARCHAR , if you serialize and de-serialize only in your .net business layer.

But what if you want to create a report on this xml data?
Then you have to extract single elements from this xml string.

That's easy with XQuery in SQL Server, I thought.

That’s our table

clip_image002

Created with this

CREATE TABLE [dbo].[UnfinishedApplication](
	[ApplicationId] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
	[OrganisationId] [uniqueidentifier] NOT NULL,
	[ApplicationName] [varchar](100) NOT NULL,
	[State] [varchar](max) NOT NULL,
	[DateCreated] [datetime] NULL,
	[DateUpdated] [datetime] NULL,
	[EmpUpdated] [varchar](150) NULL,
	[EmpCreated] [varchar](150) NULL,
	[SSWTimestamp] [timestamp] NULL,
	[StepUrl] [varchar](350) NOT NULL,
 CONSTRAINT [PK_UnfinishedApplication] PRIMARY KEY CLUSTERED 
 (
	[ApplicationId] ASC
 )
) 

 

We try this:

select [State].query('/UnProcessedApplication/Title/text()')
FROM [UnfinishedApplication]

And get

Msg 4121, Level 16, State 1, Line 2
Cannot find either column "State" or the user-defined function or aggregate "State.query", or the name is ambiguous.

Because we have a VARCHAR column and not an XML column. Let’s convert it to xml, that’s easy :-)

We try this:

select convert(xml,[State]) as tempXml
FROM [UnfinishedApplication]

And get

Msg 9402, Level 16, State 1, Line 2
XML parsing: line 1, character 39, unable to switch the encoding

Arrggghhh, because:

<?xml version="1.0" encoding="utf-16"?> 
   <UnProcessedApplication xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   --- SNIP ----

We serialize this object UnprocessedApplication in our .net business layer :-|
That’s the reason we have this nice character encoding in the xml declaration element :-)

 

Solution?

We just remove the declaration and convert that to XML. Then we can use finally XQuery :-)

SELECT (convert(xml, replace([State],'<?xml version="1.0" encoding="utf-16"?>', ''))).query('/UnProcessedApplication/Title/text()')
FROM [UnfinishedApplication]

We created a view for extracting this single fields. But I think a calculated column (COMPUTED COLUMN) would be better for this.
Is this possible todo in a computed column?
Hmm….

Wednesday, March 04, 2009

LINQ: Remember to use the let keyword

 

Sample code from http://www.codethinked.com/post/2008/04/The-Linq-quot3bletquot3b-keyword.aspx

How to filter for names that are 4 or 5 and startwith or endwith vowel?
My description is more difficult to read than the actual LINQ query.

Check it out!
namelist = List<string> { …with some names… };

var names = (from p in nameList 
                let vowels = new List<string> { "A", "E", "I", "O", "U" } 
                let startsWithVowel = vowels.Any(v => p.ToUpper().StartsWith(v)) 
                let endsWithVowel = vowels.Any(v => p.ToUpper().EndsWith(v)) 
                let fourCharactersLong = p.Length == 4 
                let fiveCharactersLong = p.Length == 5 
            where 
                (startsWithVowel || endsWithVowel) && 
                (fourCharactersLong || fiveCharactersLong) 
                select p).ToList();

Wednesday, February 11, 2009

Entity Framework: Winforms Combobox Databinding is just weird...

I wanted to use Databinding on a Combobox in Winforms, like I did with Objects or a Dataset on Master-Detail relations.
Databinding with the Designer is just so easy :-)

image
Figure: Designer properties on the combobox

I have 2 Bindingsources, the Master-Bindingsource and the the Detail-Bindingsource.
I choose the Combobox and set the different properties (DataSource, ValueMember, DisplayMember)

  • I set the ValueMember to the primary key of the Detail-Bindingsource and
  • I set the SelectedValue (Databindings) to the Master-Bindingsource.Doctor (= Entity class)

  image
Figure: Combobox properties in Designer

Problem on runtime

I get the following error

Invalid cast from System.Int32 to ClientName.Business.Entities.Doctors

Reason: The Primary key (Int32) doesn’t fit into the Entity property of the Master-Table (entity)

image 
The problem is: the Entity Framework hides the foreign-key from me (DoctorsId).
I cannot bind to it in the Designer!

How to solve that?

Solution
Don’t use Databinding.
There is no easy way of converting a primary key (Int32) to the actual Entity, with that Integer.
So, do it manually! (AAAAAARRRRRRRGGGGGHHHHHH)

   private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //HACK: AARRRGHHH: Why I have todo this manually??
            // With other Objects or Datasets we can do this in Designer
            Doctors preferredDoctor = comboBox1.SelectedValue as Doctors;
            if (preferredDoctor != null)
            {
                if (CurrentPatientFromBindingSource != null)
                {
                    CurrentPatientFromBindingSource.Doctor = preferredDoctor;
                }
            }
        }

        private void LoadDoctors()
        {
            doctorsBindingSource.DataSource = patientsBL.GetDoctors();

            //HACK: Arrggghhh: Why do I have todo this manually?
            comboBox1.SelectedItem = CurrentPatientFromBindingSource.Doctors;
        }

Todo: Investigate if Linq to Entites provides a flag to configure: Show Foreign Key property for entity

Monday, February 02, 2009

Entity Framework: Why not use Bindingsource.AddNew for creating new objects...

Assuming that you have a Detail Form with a Bindingsource, and the Bindingsource has as Datasource a IQueryable or something derived from that.

image BAD

If you use the Bindingsource to create new objects like this:
      bindingSource.AddNew(); 
your record is detached, and your business rules fire on Save (probably to late for Winforms)

image BETTER

Use
      bindingSource.DataSource = Business.AddNewObject(); 
Your record is attached, and business rules fire OnChange

Assuming you have a Business method like this.

      public Patients AddNewObject()
      {
          MyObject p = new MyObject ();
          // SetDefaultValues(p);
          DBConnection.AddToMyObject(p);
          return p;
      }

Tuesday, January 27, 2009

microsoft crm 4 - tips and tricks

while i am enjoying the sun in melbourne, be sure to check out our tips and tricks on CRM 4. http://ssw.com.au/ssw/standards/rules/rulestobettermicrosoftcrm.aspx

Tuesday, December 30, 2008

Winforms UI Best practices: Form.AutoValidate = EnableAllowFocusChange

Set on every form: Form.AutoValidate = EnableAllowFocusChange

 

image
image Figure: Form.AutoValidate = EnablePreventFocusChange, prevents you from leaving your textbox until your data entry is correct

 

image
image Figure: Form.AutoValidate = EnableAllowFocusChange with Errorproviders tell you bad data entry, but let you change to other controls