Solibulo

Uninteresting things
2008-12-10 15:17
by softlion

I like these two linq extensions methods Action<T>() and Append<string>() which are missing from the base implementation of IEnumerable<T> :

 

   public static class LINQExtension
    {
        public static void Action<T>(this IEnumerable<T> list, Action<T> action)
        {
            foreach (var t in list)
                action(t);
        }

        public static string Append(this IEnumerable<string> list)
        {
            StringBuilder sb = new StringBuilder();
            list.Action(s => sb.Append(s));
            return sb.ToString();
        }
    }

 

Sample usage:

// Compute the MD5 hash of a string
public string ComputeMD5Hash( string signatureContent )
{
  StringBuilder signature = new StringBuilder();
  MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(signatureContent)).Action(b => signature.AppendFormat("x2", b));
  return signature.ToString();
}

 

Comments (0) RSS comment feed | tags: ,

Yesterday I found what can easily be named THE bug of the year. Even I can named it the biggest bug in the last 4 years. It affects nearly all of our past projects with different degrees of impact.

It is documented in MSDN as a feature in a small note in the description of the SqlConnection.BeginTransaction .NET method (see references below).

Let me explain the context first so you really understand the bug and how to fix it.

 

Imagine you have a web application created using ASP.NET, and a SQL Server data storage.

To construct a web page, your ASP.NET code will query 3 times data on the SQL server.

The 1st and 2nd queries are executed inside a transaction which runs under a non default isolation level  READ UNCOMMITTED.

The last query is executed alone, completely separated from the previous ones. This query is using the with(READPAST) option in one of its statement.

If you run  your application, you'll see a nice .NET error page telling you that READPAST can not be used in this transaction isolation level (it does not tell you which).

 

So first you debug your application and you check in which isolation level you are. This is easily done using this query:

 

select
      transaction_isolation_level,
      last_request_start_time,
      *
from sys.dm_exec_sessions

 

And you'll find what ? That instead of being the default READ COMMITED isolation level, the query is executed under READ UNCOMMITTED !

Have you guessed why already ? Well it is because of the "feature" of the transaction handling combined with the feature of the SQL connections pooling implemented in ADO.NET.

Connection pooling makes .NET reuse existing SQL connections which is an efficient way to use this network resource.

In our case,  a connection is created by the first query and is used by the whole transaction. When closed by code, the connection is not closed but moved to the connections pool (with a TTL so it won't last forever if not used).

For the third query the code creates a new connection, which the library converts to a 'get the opened connection from my connections pool'.

 

Now read the note from MSDN :

After a transaction is committed or rolled back, the isolation level of the transaction persists for all subsequent commands that are in autocommit mode (the SQL Server default). This can produce unexpected results, such as an isolation level of REPEATABLE READ persisting and locking other users out of a row. To reset the isolation level to the default (READ COMMITTED), execute the Transact-SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED statement, or call SqlConnection..::.BeginTransaction followed immediately by SqlTransaction..::.Commit. For more information on SQL Server isolation levels, see "Isolation Levels in the Database Engine" in SQL Server 2005 Books Online.

 

What happens here is that the first connection is returned to the pool but the transaction isolation level is not reset to its default value. So our 3rd query will execute and fail unexpectedly because the with(READPAST) option is not compatible with an isolation level equals to read uncommited.

 

How to fix this ?

Before closing your connection, after a transaction where you know you change the default isolation level, just execute this code wich resets it to the default READ COMMITED or wathever you set to be the default:

myConnection.BeginTransaction().Commit();

 

 

References:

SqlConnection.BeginTransaction .NET method and the note explaining the "feature".

.NET SQL connection pooling (ADO.NET 2.0)

 

Comments (0) RSS comment feed | tags: ,
Using Guids as IDs in a database table, using these IDs in a xml typed field in another table, and building this xml in C# can lead to a non working sql query.
SQL Server converts uniqueidentifier to its uppercase string representation if the uniqueidentifier field is used inside an XQuery comparison expression.
But if the xml field content is built using C# (using the easy LINQ to XML for example) and you just rely on the default ToString method to insert the Guid in the XML you'll end up with a LOWERCASE string representation of this Guid.
So we have SQL converting by default uniqueidentifier to uppercase, and C# to lowercase.
If you rely on defaults any comparison done between uniqueidentifier in this cutting edge xml/sql technology will fail.

Notes:
The xml type is a new native type available since SQL Server 2005. I use it essentially to simplify the model for 1-N relations by storing ids of the N table in a field of the 1 table instead of creating this dummy relationship table I always hated. This without giving up performance, as long as you setup the new special xml indexes for the xml typed field. See references below for the full documentation.

A uniqueidentifier is a 16 bytes (128 bits) value which is used by the default implementation of User/Membership provider of the ASP.NET framework for all unique IDs.

With the xml data type SQL 2005 introduced "methods" that can be used to efficiently query the xml data and use it as if it was a normal table : exists(..), value(..), ...
A common parameter for these methods is an XQuery string, where XQuery is a SQL Server specific language based on XPath, with at least 2 useful efficients extensions in the sql namespace:
sql:variable(..) which is replaced by the value of an existing variable
sql:column(..) which is replaced by the value of any table row available in the t-sql query


References:
SQL Server xml data type

XML indexes
XML type query methods
XQuery language reference
Comments (0) RSS comment feed | tags: ,

Today I created my first Silverlight 2 application and my first control : a simple ball. The aim was to evaluate how easy it is to create a Silverlight 2 application and a control, and to test SL display smoothness and speed.

The ball has an update method which is called for each ball instance at most every 25ms through the application's CompositionTarget.Rendering event. I don't know if it is the best way to do procedural animation, but it sure is a way.

This event fires before each frame is rendered, like the well known frame technics in Flash. But unlike Flash, the frame rate is not constant and depends on the running machine and the silverlight application load.

I may try later using a worker thread and the InvalidateArrange() call combination. 

 

This application displays the framerate computed over the last second, creates a new ball object each time the mouse is moved over its window, and displays the total number of balls created and animated.

 

If you take a look at the result, you'll immediatly see that frame displays are not synchronized with the graphic card's vertical sync, which results in ugly breaks in the animation.

The animation slows when the mouse is moved over it : that confirms what the documentation says about the CompositionTarget.Rendering event, so we can not complain Sealed

 

 

 

Please post your FPS, ball count, and OS in the comment section.Try to get exactly 1000 or 2000 balls.

 

References

How to declare a Custom User Control from a XAML page

This app uses a fixed version of PathTextBlock silverlight control to display a text with a stroke (in fact this control converts text to glyphs which does support stroke and fill).

Configure IIS for hosting Silverlight 2 applications (don't forget to stop/start your IIS server after)

Silverlight 2 control lifecycle

 

 

La conférence pour développeurs professionnels de Microsoft s'est terminée le 30 octobre dernier, avec des informations sur le C#4 qui va bentôt sortir et même la version suivante (session de Anders Hejlsberg).

Résumé:

 

C#1 a été initié en 1998, avec la création du MSIL et de la gestion de la mémoire automatique. La version 1.1 a apporté des modifications majeures pour rendre le language utilisable.

 

C#2 a corrigé toutes les erreurs du C#1 et du MSIL1 en apportant le plus qui existait encore dans le C++ à savoir les generics (templates en C++).

 

C#3 (et 3.5) a amélioré le compilateur pour supporter LINQ, une syntaxe ressemblant au SQL pour manipuler facilement des listes. C'est la première fois qu'un langage réussit cette prouesse et je crois pour ma part que ca a été une avancée majeure dans les languages de développements qui met à la traine Java et C++. LINQ intervient également dans une stratégie d'optimisation automatique du logiciel pour le multicore. Le 3.5 intègre également les fonctions anonymes qui ont fait la force du javascript et du PHP, et le type delegate qui représente une fonction typée (très utilisé en C++ sous forme de pointeur typé).

 

C#4, avec Visual Studo 2010, pompe encore quelques goodies à Javascript avec le nouveau type "dynamic" (pratique pour COM) qui représente un objet non typé (eh oui ca peux faire rire !) sur lequel on peux appeler des propriétés ou méthodes non connues à la compilation. Ecrire des macros Excel ou Word en C# ou .NET va peux être devenir une réalité et enfin remplacer le très vieux VBA. Dommage que cela arrive si tard ! C#4 ajoute également les paramètres de fonction optionnels (merci C++) et nommés (extension pratique qui manque à C++), ainsi qu'une amélioration des generics et des delegates utile au compilateur.

 

Enfin la version suivante (C# 4.5 ?) devrait intégrer le "Compiler as a Service" - une API pour utiliser le compilateur dans le code. Ca permet d'exécuter des bouts de code dynamiquement comme pour la fonction Eval du javascript. Ca va aussi permettre de poubelliser/remplacer le language bizarre de PowerShell. Bon ok c'était déjà possible avec la version 1.1, mais la ca devrait être encore plus facile.

 

Ex d'objet dynamic:
dynamic monObjet1 = { Code=1, Name="Parapluie" };
dynamic monObjet2 = { Code=2, Name="Casquette" };
DisplayObject( monObjet1 );
DisplayObject( monObjet2 );
...
void DisplayObject( dynamic o )
{
  Console.WriteLine( String.Format( "Code: {0}, Name: {1}", o.Code, o.Name ) );
}

 

Ex de fonction avec paramètres optionnels : (existe depuis ... 15ans dans C++ ?)

public void SaveAs( string fileName, Encoding encoding = Encoding.UTF8 ) { ... }

 

Ex de fonctions avec paramètres nommés: (n'existe pas dans C++)

SaveAs( fileName: "monFichier.xml", encoding: Encoding.ASCII );

 

Référence:

La vidéo de la session sur C#4

Visual Studio 2010 et .NET Framework 4 CTP

Un résumé des sessions du PDC par Thomas Lebrun

Comments (0) RSS comment feed | tags:
2008-10-04 21:20
by softlion

Like Script# and JSC, Haxe is another open source project which aims to unify web technologies: javascript, flash (actionscript), php, and soon maybe C#.

 

The originality of Haxe is that it has created its own language and compiler, which may generate .js, .as, .php, ... files. Haxe has its own framework fully written in Haxe with high level classes which maps to native classes in the target language. That means two things: 

  • as this is a new language the learning curve is increased (even if it mimics existing languages) and if the project stops you can forget what you learned.
  • As a meta language - a language which aims to include all features of target languages - it inherently can't supports all target language features.

Although you may now think you won't use Haxe, Haxe has one major advantage : real company websites are partially written using Haxe and have professionnal looking multiplayer games.

 

References

Haxe project: http://haxe.org/

Websites written using haxe: http://softlion.labrute.fr/ http://dinocard.net/ http://www.cafejeux.com/ ...

 

2008-10-04 00:28
by softlion

Have you ever dreamed to write javascript code in C# (or VB#) ?
Have you ever dreamed to write a Flash application in C# instead of ActionScript ?
It is now possible with either Script# or the JSC projects, both having a different approach to this same starting idea.

 

As was said, the idea is to write C# code which gets transformed somehow into javascript files. All of this using the powerful Visual Studio code editor with all its goodies like intellisense, snippets, refactoring, and the power of the C# language with support for LINQ in JSC !
How is it done behind the scene ?

 

In Script#, the C# code is parsed and compiled by the Script# compiler which outputs javascript code. Standard assemblies like system.dll must be replaced by specific Script# assemblies - this is done automatically using the correct project template in VS.

 

In JSC,  which stands for "Javascript Compiler" (which is now more than that as it generates also ActionScript Java and PHP !), the C# code is compiled by the regular C# compiler into assemblies (in MSIL), which in turn are parsed and "recompiled" by the jsc compiler into the output language (js files for javascript, as files for actionscript, ...).That means LINQ (.NET 3.5) is fully supported as it is only a syntax evolution which is completely transformed into "MSIL 2.0" (.NET 2.0) by the 3.5 compiler. You can reference any .NET assembly you want, but many built-in functions won't work as they depend on low-level system functions. JSC provides assemblies declaring specificities of each target language in its own namespace, as well as extension methods to help working with the target language objects.

Example:

    [Script, ScriptApplicationEntryPoint]
    [SWF(backgroundColor = 0xcccccc)]
    public class MyFlashMainClass : Sprite
    {
        Sprite mc;
        Sprite currentDraggedSprite;
        TextField t4;

        public MyFlashMainClass ()
        {
            var c = new Sprite();
            c.graphics.beginFill(0xf8f8f8);
            c.graphics.drawRect(1, 1, stage.stageWidth-2, stage.stageHeight-2);
            c.graphics.endFill();
            c.AttachTo(this);
            c.doubleClickEnabled = true;

            stage.frameRate = 30;
            stage.focus = this;
.....

 

Which one is better ? My heart goes to JSC as I'm fond of LINQ, it's anonymous delegates syntax and extension methods, even if Script# seems better documented.
I've successfully created my first Flash application using JSC and I'm very proud ! So it really works ! Even if there are syntax tricks and the needs to know basic flash programming to make it work.

 

References

JSC: http://jsc.sourceforge.net/

Script#: http://projects.nikhilk.net/ScriptSharp/

 

Today I present an easy to use open source gravatar control.
To show a gravatar logo of one of your visitor you'll need only the visitor's email.

 

I took the source code from the reference implementation advertised on Gravatar from freshclickmedia (see references at the bottom of this article), updated it to match the new gravatar API, and among other things fixed the ViewState implementation.

 

Basic usage
1) In your project add a reference to the assembly FreshClickmedia.Web.dll
2) At the top of your aspx or ascx page add:
<%@ Register TagPrefix="fcm" Assembly="FreshClickmedia.Web" Namespace="FreshClickMedia.Web.UI.WebControls" %>
3) In your page add this tag where you want the logo to appear:
<fcm:Gravatar ID="GravatarImage" runat="server" Email="thisemaildoesnotexist@thisemaildoesnotexist.com" />

 

References
Gravatar: http://www.gravatar.com/
Original ASP.NET control from freshclickmedia: http://www.freshclickmedia.com/blog/2008/06/aspnet-gravatar-control-update-full-source-included/

 

Downloads
.NET Assembly only
Full source code with example web site

 

Examples

My email address, size of 80 pixels:
<fcm:Gravatar ID="Gravatar1" runat="server" Email="putexistingemailhere@putexistingemailhere.com" OutputGravatarSiteLink="true" Size="80" />
Gravatar

No email address, with default image (absolute url) specified:
<fcm:Gravatar ID="Gravatar2" runat="server" Size="80" DefaultImageUrl="http://farm3.static.flickr.com/2375/2552064340_192825f989_o.jpg" />
Gravatar

Email address not associated with Gravatar, with no default image (identicon):
<fcm:Gravatar ID="Gravatar3" runat="server" Email="thisemaildoesnotexist@thisemaildoesnotexist.com" />
Gravatar

Email address not associated with Gravatar, with no default image (wavatar):
<fcm:Gravatar ID="Gravatar4" runat="server" Email="thisemaildoesnotexist@thisemaildoesnotexist.com" DefaultImageType="Wavatar" />
Gravatar

Email address not associated with Gravatar, with no default image (Monsterid):
<fcm:Gravatar ID="Gravatar5" runat="server" Email="thisemaildoesnotexist@thisemaildoesnotexist.com" DefaultImageType="Monsterid" />
Gravatar 

 

Transfering rows from a development database to a production database can quickly become a nightmare.
To avoid this you should think your data model to deal with this new constraint: each row must be uniquely identified by a value which does not change in time and can be recomputed in a similary table in another database at anytime.

 

This unique value can be a hash. A hash is an asymetric cryptography function which always generates the same value when the same input is specified, and has a 99,9% chance to generate a different values with different inputs.


That means to generate our small hash to identify a row, we should find a primary key on our table which does not depend on an identity column. We can not use variable date fields nor uniqueidentifier fields as they are generated on row creation and will be different if we create a row with the same data on another database. This primary key can be a composite string key made of parts of the other table columns.

 

Using the HashBytes function with the SHA1 hash function in SQL 2005 generates a binary(20) result. With SQL 2000 you may use the checksum() function.

 

Example:

CREATE TABLE [dbo].[ITEM](
    [ITEMID] int IDENTITY(1,1) NOT NULL,
    [NAME] nvarchar(50) NOT NULL,
    [DESCRIPTION] nvarchar(200) NOT NULL,
    [HASH] AS (hashbytes('SHA1',[NAME]+[DESCRIPTION])),
CONSTRAINT [PK_ITEM_ITEMID] PRIMARY KEY CLUSTERED
(
    [ITEMID] ASC
),
CONSTRAINT [IX_ITEM_HASH] UNIQUE NONCLUSTERED
(
    [HASH] ASC
))
 

Limitation: HashBytes input string is limited to 8000 bytes.
Tip: you may use the undocumented function master.dbo.fn_varbintohexstr(binary hash value) to convert the binary result to a string prefixed with 0x.

Comments (0) RSS comment feed | tags: