ILogicalThreadAffinative, again.

By Jay at May 14, 2008 19:12 Tags: , ,

Ce post est également disponible en francais. 

In a previous post, I talked about a feature of the .NET framework that allows to automatically pass information from a thread to any thread it spawns.

It turns out that not only the Call Context flows to the thread pool, but it also flows to any System.Threading.Timer and to IO completion related threads, such as in Sockets.

I was taken off-guard by the fact that in early stages of the server-side remoting pipeline, there were already information in the CallContext before the incoming message was deserialized. But the content was not exactly what I was expecting; it was the data that was in the CallContext when RemotingConfiguration.Configure() was invoked.

This makes sense, all the sockets used by TcpChannel or HttpChannel are created when calling this method, and asynchronous operations are started at this time. So, to avoid having the data to flow to the other side, there are these two methods on the ExecutionContext class to Suppress the flow and Restore it, which can prevent temporarily the Call Context from flowing.

IEnumerable<T>.Any() vs. IEnumerable<T>.Count() != 0

By Jay at May 10, 2008 11:10 Tags: , ,

This post is also available in french here. 

After reading this post from Eric Lippert, and reminding me that in the samples for this post, I'm using IEnumerable<T>.Count() where I'm actually not using the return value, therefore I'm enumerating through the whole collection for almost nothing.

I could have used IEnumerable<T>.Any(), which after looking at the IL code, just starts the enumeration, and stops just after one element if there is one and returns true, or if there isn't, returns false.

This is more effective, even without PLinq :)

A look at Linq to objects and the "let" keyword

By Jerome at April 26, 2008 13:08 Tags: , ,

Cet article est aussi disponible en français ici. 

I've had some time lately to use LINQ a bit more intensively and in particular to use the let keyword.

I had to process a lot of XML files placed in multiple folders, and I wanted to filter them using a regex. First, here's how to get all files from a directory tree :



  var files = from dir in Directory.GetDirectories(rootPath, SearchOption.AllDirectories)
              from file in Directory.GetFiles("", "*.*")
              select new { Path = dir, File = Path.GetFileName(file) };

At this point, I could have omitted the Directory.GetDirectories call because GetFiles can also search recursively. But since the GetFiles method only returns a string array and not an enumerator, it means that all my files would have been returned in one array, which is not memory effective. I'd rather have an iterator based implementation of GetDirectories and GetFiles for that matter, but the finest grained enumeration can only be done this way...

Anyway, having all my files, I now wanted to filter the collection with a specific Regex, as my legitimate files need to observe a specific pattern. So, I updated my query to this :



    Regex match = new Regex(@"(?<value>\d{4}).xml");
    var files2 = from dir in Directory.GetDirectories(args[0], "*", SearchOption.AllDirectories)
                 from file in Directory.GetFiles(dir, "*.xml")
                 let r = match.Match(Path.GetFileName(file))
                 where r.Success
                 select new {
                    Path = dir,
                    File = Path.GetFileName(file),
                    Value = r.Groups["value"].Value
                 };


This time, I've introduced the let keyword. This keyword is very interesting because it allows the creation of a query-local variable that can contain either collections or single objects. The content of this variable can be used in the where clause, as the source of another "from" query, or in the select statement.

In my case, I just wanted to have the result of the Regex match, so I'm just calling Regex.Match to validate the file name, and I'm placing the content of a Regex group in my resulting anonymous type.

Now, with all my files filtered I found that some XML files were not valid because they were not containing a specific node. So I filtered them again using this query :



    var files2 = from dir in Directory.GetDirectories(args[0], "*", SearchOption.AllDirectories)
                 from file in Directory.GetFiles(dir, "*.xml")
                 let r = match.Match(Path.GetFileName(file))
                 let c = XElement.Load(file).XPathSelectElements("//dummy")
                 where r.Success && c.Count() != 0
                 select new {
                    Path = dir,
                    File = Path.GetFileName(file),
                    Value = r.Groups["value"].Value
                 };

I've added a new let clause to add the loading of the file, and make sure there is a node named "dummy" somewhere in the xml document. By the way, if you're looking XPath in XLinq, just look over there.

You may wonder by looking at this query when the load is actually evaluated... Well, it is only evaluated when the c.Count() call is performed, which is only after the regex has matched the file ! This way, I'm not trying to load all the files returned by GetFiles. You need to always remember that queries are evaluated only when enumerated.

In conclusion, Linq is a very interesting piece of technology, definitely NOT reserved to querying databases. What I like the most is that one can write code almost without any loop, therefore reducing side effects.

If you haven't looking at Linq yet, just give it a try, you'll probably like it :)

A bug in VS2008 Code Analysis, Generics normal and nested classes

By Jerome at April 07, 2008 19:12 Tags: , ,

I've found a few days ago a small bug in the former "FxCop" now renamed Code Analysis part of Visual Studio 2008.

While compiling this little piece of code :


public class Dummy<T> where T : IDisposable
    {
        public T Test
        {
            set
            {
                new NestedDummy<T>(default(T));
            }
        }

        class NestedDummy<U>
        {
            public NestedDummy(U item)
            {
                this.Value = item;
            }

            public U Value { get; private set; }
        }
    }

Which is a trimmed down version of the actual code, I saw a lot of errors like this :

MSBUILD : error : CA0001 : Rule=Microsoft.Reliability#CA2001, Target=ConsoleApplication1.Dummy`1+NestedDummy`1.#.ctor(!1) : The following error was encountered while reading module 'ConsoleApplication1': Could not resolve member reference: ConsoleApplication1.Dummy`1<type parameter.T>+NestedDummy`1<type parameter.U>::set_Value.

This means that for some reason, the Code Analysis tool is unable to parse the metadata to check for some analysis rule. This is not a blocking bug since it does not prevent the build from ending properly, but it displays a lot of error messages, which can be disturbing.

To fix to, I found two solutions : Either move the nested class out of its parents class, or remove the generic constraint on the parent class.

I posted the bug on Microsoft Connect, and I was pleasantly surprised to see that it has already been processed and David Kean from Microsoft wrote that the fix will be available in the next Service Pack of Visual Studio 2008.

Not a big issue but still, nice to see that Connect has an impact.

.NET Threads, CallContext and ILogicalThreadAffinative

By Jerome at February 10, 2008 21:53 Tags: , ,

I've recently been looking for a way to automatically pass information from a thread's current call context to any thread that's been spawned from this thread. This can be useful for many reasons, and sometimes having some TLS information like the current user, or some custom context information.

This can be done by wrapping any thread entry point around some custom code that will effectively pass the context to the new thread. This is a bit annoying, especially if this is information that is generated internally by a framework, because it requires the user of the framework to always use the wrapping method.

There's a way around this by using the CallContext class, and particularly GetData/SetData methods. Problem is, if you set some data in the CallContext, it will not pass onto a spawned thread. Actually, it will if the type you are placing in the CallContext implements the ILogicalThreadAffinative interface.

This is a marker interface that is used to avoid context data that is not meant to "flow" through each spawned thread.

It's also interesting to know that ILogicalThreadAffinative flagged types will also be passed along to threads spawned by the thread pool, and incidentally to delegates enqueued via the BeginInvoke compiler generated method.

Finally, in case of a remoting call, any ILogicalThreadAffinative flagged type will also serialized to the remote context and be serialized back to the local context.

Being able to step through the Framework's code has been somehow a time saver to better understand this :)

Visual Studio 2008 : Where is my Solution Explorer item sort gone ?

By Jerome at December 11, 2007 13:58 Tags: , ,

As a new user of VS2008 and senior user of VS2005, you may just just start to convert your projects to VS2008. Good. Then you look at your solution and start to look for your favorite project in the Solution Explorer and have trouble finding it... Of course ! The list is not sorted...

You may wonder, where is that sorting gone ? Well, I don't know exactly but it seems that if you select a project, press F2, then enter without modifying a thing... The tree sorts itself out! The bad thing is that you can't save that sorted list, as it seems that it is only the TreeView that sorts the item list, not the internal list that is sorted... I know for a fact that there are some PowerToys that sort the entries in the SLN file, I'll try to look for that.

How could something as visible as this has passed through the beta phase ? :)

The (non generic) System.Action delegate

By Jerome at December 09, 2007 22:33 Tags: , ,

There's been one delegate I wish would have been integrated in .NET 2.0 :

1:
2: namespace System
3: {
4:   public delegate void Action();
5: }

Well, it's been added to the .NET framework 3.5. That will avoid me to create here and there an empty delegate that returns nothing and takes nothing in parameter. It's particularly useful with anonymous methods.

My discovery of that particular type is a bit odd though. A big project I'm currently working on is defining this type :

1:
2: namespace T1 { public enum Action { A } }

"T1" is made up, "Action" is not. And it's being used like this :

1:
2: Action a = Action.A;

And it compiled just fine using .NET 2.0. During a migration to the .NET Framework 3.5, I came across some compilation problems telling me that the resolution of "Action" was ambiguous. I thought at first that this was because of a change in the resolutions of types in C# 3.0, but after a bit of digging I found out about that non-generic System.Action delegate, which is defined in System.Core.dll. By the way, they also added some other System.Action overloads with two, three and four generic parameters.

Reflector tells me that the non generic version is being used by System.Linq.Expressions.Expression. I'm guessing that might be used by LINQ in some way... maybe by some generated code.

Binding a C# property to a WPF validated Control

By Jerome at August 29, 2007 05:48 Tags: , ,

The DataBinding in WPF allows the binding of control properties to many things, like other control properties, arrays, data providers, ... But it can also bind a control property to a property defined by code on the C# side.

It is interesting to bind to C# property to be able to have the integrated WPF validation and still use a simple property from the code. In that case, I wanted to have the validation of a TextBox displaying a DateTime object.

Here's how to do this.

On the C# side :


public partial class Window1 : Window

  public Window1() 
  {   
    MyDate = DateTime.Now;
    InitializeComponent();
  }
  public DateTime MyDate { get; set; }
}
 

Note that I'm using the latest C# 3.0 syntax to declare variable-less properties. This is compiler trick, the variable is still declared at compile time, but since I don't need to have a specific code in the get or set accessor, it can stay in this short form.

Now on the XAML side :


<Window ... >

  <TextBox Width="100" Height="20">

    <Binding Path="MyDate" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}" UpdateSourceTrigger="PropertyChanged">

      <Binding.ValidationRules>

        <ExceptionValidationRule />

      </Binding.ValidationRules>

    </Binding>

  </TextBox>

</Window>

The interesting part here is the use of RelativeSource and the FindAncestor mode. Here, we're looking for the property MyDate from the nearest ancestor instance of the Window type, from the current instance.

This way, you'll have a validated date time in your property value. Just make sure you're checking that the value is really valid using the System.Windows.Controls.Validation class.

WCF, NuSOAP and ArrayOfString

By Jerome at April 16, 2007 15:21 Tags: , , , ,

When exposing a WebService via WCF, you might want to expose something like this :


[DataContract]
public class SomeContract
{
  [DataMember] 
  public string[] Values { get; set; }
}

For that particular data contract, WCF will be generating a WSDL with something like this :


<xs:complexType name="SomeContract">

  <xs:sequence>

    <xs:element minOccurs="0" name="Values" nillable="true"

                type="q1:ArrayOfstring"

                xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />

  </xs:sequence>

</xs:complexType>

With ArrayOfString being defined like this :


  <xs:schema elementFormDefault="qualified"

             targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"

             xmlns:xs="http://www.w3.org/2001/XMLSchema"

             xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">

    <xs:complexType name="ArrayOfstring">

      <xs:sequence>

        <xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string"/>

      </xs:sequence>

    </xs:complexType>

    <xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring"/>

  </xs:schema>

In general, that would be fine. The type "ArrayOfString" is defined in a different namespace, but this should not be a problem.

So, to use that particular type in a method call, you should have a document like this one :


<SomeContract>

  <Values xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">

    <a:string>My Value</a:string>

  </Values>

</SomeContract>

"string" elements are contained in a different namespace from the SomeContract element. However, the NuSOAP stock version 0.7.2 has a problem with that kind of schema, and generates instead something like this :


<SomeContract>

  <Values>

    <string>My Value</string>

  </Values>

</SomeContract>


When the WCF deserializer receives a document like this one, it does not find the "Values" member in the namespace he's looking and ends up creating a SomeContract instance with a null array of strings.

Since there's no way of fixing NuSOAP, you may need to tweak your contract to help NuSOAP serializing your data without a namespace.

The CollectionDataContract attribute seems to be the way to go, since there is a way to specify the namespace to use when generating the metadata. The service contract then looks like this :


  [DataContract(Namespace = "http://my.name.space")] 
  public class SomeContract 
  { 
    [DataMember] 
    public ArrayOfString InvalidIdentifiers { get; set; } 
  } 

  [CollectionDataContract(ItemName="string", Namespace="http://my.name.space")]
  public class ArrayOfString : List<string> { } 

Thereby placing everything in the "http://my.name.space" namespace.

You might need to tweak a bit the ArrayOfString class, especially if you need to assign it from an actual string[] instance, but you get the idea.

WCF WebService behind a NAT Gateway

By Jerome at April 15, 2007 11:06 Tags: , , ,

I'm currently working on a WCF service that's exposed via a basicHttpBinding, with some exposition of the metadata via a WSDL url.

The metadata generator has been improved a bit since it is now split into multiple files, with references from the first wsdl to other URI's. There's not much to do to have that WSDL generated, and the generator take the liberty of using the machine's name to create reference URIs.

Most of the time, this is a good idea, but sometimes when your machine is behind a NAT gateway doing some port forwarding, your machine probably won't have the public FQDN used to access your gateway. You then end up with a root document referencing URI's with a host name that is not valid on the other side of the gateway.

The solution to change that behavior is quite simple : Just change the host name IIS is listening on. Use the MMC snap-in, and specify that your port 80 (or whatever port you're using) is listening on your external FQDN. WCF will then use that host name when generating URI's. Also don't forget that if you specify a host name, you might need to add an other entry to be able to access your website using "localhost".

This operation is also needed for servers farm when doing some load balancing.

About me

My name is Jerome Laban, I am a Software Architect, C# MVP and .NET enthustiast from Montréal, QC. You will find my blog on this site, where I'm adding my thoughts on current events, or the things I'm working on, such as the Remote Control for Windows Phone.