Microsoft DevDays 2011– I’ll be there

by Sander Gerz April 12, 2011 22:46

 

This year, I’ll be at the annual Microsoft DevDays in The Netherlands where you can ask me anything on web development. My base of operation at the conference will be somewhere in the ‘Ask-the-Experts’ area. Though you may also find me hanging around in the Community Lounge.

But if time permits, I seriously hope to find some time to go some sessions too. With many interesting sessions running in parallel and with limited time, it’s important to have some criteria up front to make a decision where to go, and what to skip. These criteria usually involve: speaker (good) and topic (interesting). That’s nice and easy, but how do know if a speaker is any good, and if the topic is interesting? Hopefully, some tips below may help in that respect.

First, I set a goal for my self. What is it that I want to take away from the conference? Do I have a current project or a future one in mind? Is a certain problem bugging me that needs to be resolved? That makes the topic more important than the speaker. On the other hand, I also like to be surprised. It can soon get boring and a waste of time to attend a session on a subject that you are very familiair with already. With a conference like TechEd I always learn most from the IT Pro sessions, because that’s an area that I usually only follow from afar. And you learn about stuff you hardly knew existed. Granted, it’s also stuff that’s not readily applicable in my own daily work.

Anyway, being interested in web development, and already trying to keep track of most stuff Microsoft pushes out. Here’s a list of sessions I’d like to attend on Day 1:

1. 09:15 - 10:45  The Keynote (link). Especially Rob Miles can put a smile on my face, but I’m not sure what his role will be as he’s only mentioned as a speaker and not his topic.

2. 13:30 - 14:45  Windows Azure AppFabric: Building, Managing, and Connecting High-Density, Multi-Tenant Cloud Applications (link). It’s quite a long title, but both the topic and speaker are interesting. The timeslot is difficult in that there are quite a few interesting sessions going on at the same time. Fallback-sessions, in case I can’t find the room (yes, that happens Knipogende emoticon ) or it’s too crowded would be: Unlocking the Secrets of REST with WCF (link) and This Costs What? Estimating Costs in the Azure Cloud (link).

3. 15:05 - 16:20  Taking Control of your World with the .NET Micro Framework (link). Again with Rob Miles, just for the fun of it.

4. 16:30 - 17:45  This slot is again a challenge as several topics interest me, like What's New in Silverlight 5 (link), Test Driving ASP.NET MVC (link) but being really into C#, I should probably not miss Behind the Scenes of 10 C# Language Features by Bart De Smet (link).

In the evening, there’s GeekNight where the focus is on fun and less on function although the two can certainly mix well together. Mobile is hot it seems with cool sessions like:

Developing iPhone/iPad, Android and Windows Phone 7 Applications with C#, Visual Studio, Mono Touch en Mono Droid (link), Windows Phone in Rhyme and 3D (link) and Hoe Ontwikkel je een XNA Game voor de Phone 7, Xbox 360 en de PC met Dezelfde Code Base (link).

Actually, more sessions in the evening make me curious, but I haven’t managed to implement the me.Clone() method.

Then there’s Day 2, with these sessions on my agenda:

1. 09:15 - 10:30 HTML 5 - That's What You Need to Know Today (link) because I really need to get an update on the status of HTML5 and see if it’s usuable on websites with a large audience or not.

2. 10:50 - 12:05 Demystifying the .NET Asynchronous Programming Landscape (link) since async programming can be a lot simpler. At the same time, I’m running into disk I/O as the next bottleneck.

3. 13:15 - 14:30  Entity Framework 4 Tips en Tricks (link) although I’m a bit confused by the level-indicator: a 200-level ‘PowerTraining’ on subject that the audience should be familiar with. Alternatively, I could try Advanced Debugging with Visual Studio 2010 (link) with a great speaker on a difficult topic.

4. 14:50 - 16:05 WCF Web APIs, HTTP your way (link) even though I’m not a big fan of WCF (talking about configuration hell) but exposing APIs on a couple of projects I’m working on can be a great boost for exposure.

Not all timeslots are covered in this list. As I said, I should be at the Ask-the-Expert area as well. So it seems, you will only find me there on Day 1 from 10:45 to 13:30  and on Day 2 from 16:15 until the conference ends Knipogende emoticon . In summary, there are more interesting sessions than time permits, so this year’s Microsoft DevDays should be a blast. Hope to see you there!

Currently rated 4.2 by 290 people

  • Currently 4.155173/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET

Working around "Cannot create an object of type 'System.Boolean' from its string representation"

by Sander Gerz April 18, 2009 21:05
In ASP.NET Web Forms most times there’s a need to set ASP.NET Server Control properties at runtime. This, for instance:
<asp:Button runat="server" id="Button1" visible="true" />

It is pretty straightforward to set the value of the visible-property in a code-behind page, like so:

protected void Page_Load(object sender, EventArgs e)
{
Button1.Visible = false;
}

However, it would be nice if you could to things like this

<asp:Button runat="server" id="Button1" visible='<% =User.IsInRole("Editor")%>' />

One might expect that that the expression above is evaluated such that the visible-property is true when the current User has the role of Editor and false if not. Unfortunately, executing this bit results in an exception:
Cannot create an object of type 'System.Boolean' from its string representation
'<%= User.IsInRole("Editor") %>' for the 'Visible' property. 
These problems are discussed also here and here. The reason is that the string-value of each property on a server-control is evaluated and parsed to its desired type. So you could set the property to "True" or "true", but not to an expression that needs to be evaluated.
The solution is to use a databinding syntax, which is pretty easy to do
<asp:Button runat="server" id="Button1" visible='<%# User.IsInRole("Editor") %>' />

As you can see, we simply add the pound/hash sign and remove the equals from the expression. This databind-expression is interpretered quite differently at runtime.

  • <%= %> is in reality the same thing as Response.Write().

  • <%# %> is more in related to assigning a value to an object. In the ASP.NET lifecycle, the <%# %> operators are evaluated before the page writes the first byte to the response buffer.

The problem with using a databinding expression is that you need to execute a DataBind() method either on the control itself or on the entire page. Executing DataBind() at page level can have negative side effects when you have multiple controls on the page with associated databinding logic. DataBind() at pagelevel triggers events, perhaps at times when you don’t want them. Using DataBind() in the codebehind for relevant controls defeats the idea a bit that we want to set a property with some simple rules and preferably in one place only.

A solution for this is to add another property (or attribute if you will), that just executes DataBind() on the current control. Something like this:

<asp:Button runat="server" id="Button1" visible='<%# User.IsInRole("Editor")%>'
code='<% DataBind(); %>' />

 

Unfortunately, that doesn’t work, because at runtime, the ASP.NET rendering engine will complain that a Button-control doesn’t have a property “code” so it doesn’t know what to do with it. However, we can trick it to ignore the property for rendering, but still execute the code, like so:

<asp:Button runat="server" id="Button1" visible='<%# User.IsInRole("Editor")%>' meta:code='<% DataBind(); %>' />


Prefixing the attribute with the text meta: with make the renderer ignore the value, but the code will still execute. Please note that the example uses meta:code, but it doesn’t really matter what name you give the attribute. It could be meta:execute or meta:whateveryouwant, as long as it’s not meta:resourceKey, because that property has special meaning.

It may not be the most elegant solution, but hey, if it works, I’m ok with it. With the rise of ASP.NET MVC we’ll probably see more of this type of coding anyway.

Currently rated 2.9 by 76 people

  • Currently 2.881579/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Sorting generic lists; can it be done with less code?

by Sander Gerz December 15, 2008 09:42

Trying to find a method to sort a generic list, I found this solution. While this seems like an elegant solution, I found it a bit much code for my purpose. I only wanted to sort a list with objects that had a date property. This is the shortest version I could come up with (C# 3.0):

list.Sort((p1, p2) => p1.DateAdded.CompareTo(p2.DateAdded));

Obviously, sorting on any other property is just as simple:

list.Sort((p1, p2) => p1.ProductName.CompareTo(p2.ProductName));

Here's the class definition and some sample data to do the exercise yourself if you want to.

    class Product

    {

        public int ProductId { get; set; }

        public string ProductName { get; set; }

        public decimal Price { get; set; }

        public DateTime DateAdded { get; set; }

    }

       List<Product> list = new List<Product>() {

            new Product() {ProductId=1, ProductName="Item1",

                Price=20.00M, DateAdded=DateTime.Parse("2008-11-02")},

            new Product() {ProductId=1, ProductName="Item2",

                Price=10.00M, DateAdded=DateTime.Parse("2008-04-02")},

            new Product() {ProductId=1, ProductName="Item3",

                Price=40.00M, DateAdded=DateTime.Parse("2008-02-03")},

            new Product() {ProductId=1, ProductName="Item4",

                Price=30.00M, DateAdded=DateTime.Parse("2008-11-01")}};

Enjoy.

Currently rated 2.0 by 6 people

  • Currently 2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Visual Basic losing interest?

by Sander Gerz November 24, 2008 12:08

An interesting tool from Google allows you to display the trend of search terms over time. Out of curiosity, I looked at the popularity of the terms “visual basic” and “c#”. It doesn't look too good for VB.

(Red line shows interest in visual basic, blue is C#). Another interesting insight is the region where people seems to be searching for C# (India). And what about C# versus Java? Interesting findings.

 

Currently rated 2.3 by 3 people

  • Currently 2.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

LINQ to XML instead of XPath

by Sander Gerz October 06, 2008 10:13

Working on a new project, I needed to read some elements from an XML file. As a matter of habit, I used XPath, but later I figured this was a good opportunity to try it out using LINQ. So here goes.

The XML source is a file, stored as Resources.xml with the following contents.

<?xml version="1.0" encoding="utf-8" ?>

<resources>

  <culture code="en-US" >

    <resource key="MetaData.Description" value="&quot;Realtime data on ... !&quot;" />

    <resource key="MetaData.Keywords" value="&quot;images, keyword1, keyword2, keyword3&quot;" />

    <resource key="Homepage.Title" value="just a random title" />

  </culture>

  <culture code="nl-NL" >

    <resource key="MetaData.Description" value="&quot;Realtime beelden ...&quot;" />

    <resource key="MetaData.Keywords" value="&quot;beelden, plaatjes, etc.&quot;" />

    <resource key="Homepage.Title" value="Een willekeurige titel" />

  </culture>

  <culture code="fr-FR" >

    ...

  </culture>

</resources>

The relevant data is in the value-attribute. The input parameters is culture of type CultureInfo and resourceKey of type string. resourceFile holds the path to the XML file.

The XPath version of getting to that data is this:

XmlDocument resourceXml = new XmlDocument();               

resourceXml.Load(resourceFile);

string xpathQuery = string.Format("//culture[@code='{0}']/resource[@key='{1}']", culture.Name, resourceKey);

XmlNode resourceElement = resourceXml.SelectSingleNode(xpathQuery);

if (resourceElement != null) resourceValue = resourceElement.Attributes["value"].InnerText;

Using LINQ to XML we can use the following snippet:

XDocument xdoc = XDocument.Load(resourceFile);

var q = from c in xdoc.Descendants("culture")

  where c.Attribute("code").Value == culture.Name

        from r in c.Descendants("resource")

        where r.Attribute("key").Value == resourceKey

        select r.Attribute("value").Value;

if (q.Count<string>() == 1) resourceValue = q.First<string>();

Either version works fine. The only issue is that LINQ is supposed to help the developer by IntelliSense and strong typing. Unfortunately, that doesn't happen here, at least not with the elements in the XML file.

 

 

 

Currently rated 1.0 by 1 people

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Visual Studio 2008 released soon?

by Sander Gerz November 17, 2007 20:43

According to the MSDN Subscriptions WebLog we can expect to see Visual Studio 2008 to be downloadable early next week.

“Visual Studio 2008 is anticipated out early next week, with availability for Subscribers. Check out the "Top Subscriber Downloads" area on http://msdn2.microsoft.com/subscriptions for VS 2008 downloads.

You will also be able to access these downloads by clicking on the Subscriber Downloads and Product Keys links that take you to all of your downloads. ”

(source: Ken Cox)

That would be great and just in time for a session I'm doing Friday on 'what's new in Visual Studio 2008'. More details on that here: http://www.newhorizonslearning.nl/New-Horizon-s-Developers-day.554.0.html (it's Dutch).

update: RTM has been reached and VSTS 2008 can be downloaded (source).

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Migrate ClearCase to TFS: update

by Sander Gerz September 16, 2007 17:49

Recently, I started a on a new project as a development coordinator. One of the tasks we face is a migration from Rational ClearCase to Team Foundation Server. A tool that should help in doing this has just been released. What a coincidence!

The Team Foundation Server Migration Tool for Rational® ClearCase® is a tool to help automate the migration process from Rational® ClearCase® to Team Foundation Server. This tool is available as a free download for Team Foundation Server users.
 
Brian Keller also points to other useful resources as well as a blog post on migrating from ClearCase to TFS. Just what we need.
 
update:
Actually, we cannot use the tool. It appears it only works with ClearCase, and we're using ClearCase LT. The differences can be found here. Bummer.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Creating a simple captcha

by Sander Gerz June 08, 2007 09:01

The new DevTips.NET website allows for people to comment on most content, unlike the old site. Obviously this opened up possibilities to add comment spam on all the places. There is a common technique to counter this, called CAPTCHA or “Completely Automated Public Turing test to tell Computers and Humans Apart”. There is also an easy ASP.NET control that you can implement on a website to implement this captcha from Miguel Jimenez. I use it on this blog. For some reason though, the captcha-image didn't display on the new site. Several options are available: figure out what's wrong, look for another control or... build one myself. Thinking that it shouldn't be too hard, and being a developer, I obviously chose the last option. So here goes:

First, we need an image to display. I chose to use an HttpHandler for this. Seemed like a good choice, since we only need to Response.Write an image, and store the generated code somewhere.

<%@ WebHandler Language="C#" Class="HipHandler" %>

 

using System;

using System.Web;

using System.Drawing;

using System.Drawing.Imaging;

using System.Drawing.Drawing2D;

using System.Drawing.Text;

 

public class HipHandler : IHttpHandler {

 

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "image/jpeg";

        SendImage(context);

    }

 

    public void SendImage(HttpContext context)

    {

        int fontSize = 24;               

        int width = 100;

        int height = 30;

 

        // Setup the rectangle to draw the text on

        RectangleF rectF = new RectangleF(0, 0, width, height);

        Bitmap pic = new Bitmap(width, height);

        Graphics g = Graphics.FromImage(pic);

        g.SmoothingMode = SmoothingMode.AntiAlias;               

        SolidBrush fgBrush = new SolidBrush(Color.RoyalBlue);

        SolidBrush bgBrush = new SolidBrush(Color.SkyBlue);

        g.FillRectangle(bgBrush, rectF);

 

        // Choose the font and style

        FontStyle style = FontStyle.Regular;       

        Font font = new Font("Arial", fontSize, style, GraphicsUnit.Pixel);

 

        // Make sure the text is centered

        StringFormat format = new StringFormat();

        format.Alignment = StringAlignment.Center;

 

        // Draw horizontal and vertical lines to make is less computer-readable

        Pen p = new Pen(new SolidBrush(Color.SteelBlue), 1);

        for (int i = 0; i < height; i=i+7)

        {

            g.DrawLine(p, 0, i, width, i);   

        }

 

        for (int i = 0; i < width; i=i+10)

        {

            g.DrawLine(p, i, 0, i, height);   

        }

 

        // Get 4 random characters, no weird ones

        string randomText = GenerateRandomText(4, false);

        System.Security.Cryptography.SHA256Managed hashAlg = new System.Security.Cryptography.SHA256Managed();

 

        // Hash the text so it can be verified after postback

        string hashText = HttpUtility.UrlEncode(hashAlg.ComputeHash(System.Text.Encoding.Default.GetBytes(randomText)));

        context.Response.AppendCookie(new HttpCookie("HipHash", hashText));

 

        // Write the text and send it to the browser

        g.DrawString(randomText, font, fgBrush, rectF, format);       

        pic.Save(context.Response.OutputStream, ImageFormat.Jpeg);       

    }

 

    public static string GenerateRandomText(int maxlength, bool ultraStrong)

    {

        char[] ultraChars = "!@#$%^&*~|=?{}[]qwertyuiopasdfghjklzxcvbnm1234567890!@#$%^&*~|=?{}[]".ToCharArray();

        char[] normalChars = "qwertyuiopasdfghjklzxcvbnm1234567890".ToCharArray();

 

        string password = string.Empty;

        for (int i = 0; i < maxlength; i++)

        {

            char n = ' ';

            if (ultraStrong) n = ultraChars[GetRandomNumber(ultraChars.Length - 1)];

            if (!ultraStrong) n = normalChars[GetRandomNumber(normalChars.Length - 1)];

            if (i % 2 == 0)

                password += n.ToString().ToUpper();

            else

                password += n;

        }

        return password;

    }

 

    public static int GetRandomNumber(int maxvalue)

    {

        System.Security.Cryptography.RandomNumberGenerator random =

            System.Security.Cryptography.RandomNumberGenerator.Create();

 

        byte[] r = new byte[1];

        random.GetBytes(r);

        double val = (double)r[0] / byte.MaxValue;

        int i = (int)Math.Round(val * maxvalue, 0);

        return i;

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }

}

I'm reusing a method to generate random texts. It was originally intended to create random passwords, hence the variable names in the implementation of the method GenerateRandomText(). The randomly chosen four characters are displayed in the image and also stored in a cookie. No, not directly of course. The text is hashed making it impossible to read before it's stored in the cookie. Other storages, like session or response headers are unavailable or unusable in an HttpHandler. Using a session to store a code is bad practice anyway.

The second part is a Web User Control that displays the image and asks the user to enter the displayed code.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="UserControlHip.ascx.cs"

 Inherits="UserControlHip" %>

<img src="HipHandler.ashx" alt="HIP" />

Enter the code:

<asp:TextBox ID="TextBoxHip" Width="100" runat="server"></asp:TextBox>

<asp:Label ID="LabelCodeStatus" runat="server" Text=""></asp:Label>

Obviously you can modify the html of this user control to fit your needs and style. The code-behind is a bit more elaborate.

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class UserControlHip : System.Web.UI.UserControl

{

    private string m_controlToVerify;

 

    public string ControlToVerify

    {

        get { return m_controlToVerify; }

        set { m_controlToVerify = value; }

    }

 

    protected void Page_Load(object sender, EventArgs e)

    {

        if (IsPostBack)

        {

            // Verify the submitted code to the generated code

            System.Security.Cryptography.SHA256Managed hashAlg = new System.Security.Cryptography.SHA256Managed();           

            string hashText = HttpUtility.UrlEncode(hashAlg.ComputeHash(System.Text.Encoding.Default.GetBytes(TextBoxHip.Text)));

            string hashTextFromHeader =  Request.Cookies["HipHash"].Value;

            LabelCodeStatus.Text = "";

            if (hashTextFromHeader != hashText)

            {               

                // If the code is not correct, save the contents of the control to verify (usually

                // a comments-textbox) in a session so visitors don't loose their elaborate entry

                // After that, redirect to the same page

                TextBox textBoxControl = (TextBox)this.Parent.FindControl(m_controlToVerify);

                Session["HipControlToVerifyValue"] = textBoxControl != null ? textBoxControl.Text : "";               

                Response.Redirect(Request.Url.PathAndQuery);

            }

        }

        if (!IsPostBack)

        {

            TextBox textBoxControl = (TextBox)this.Parent.FindControl(m_controlToVerify);

            // If return from a redirect, meaning the code entered was incorrect,

            // fill the textbox with the session-stored entry.

            if (Session["HipControlToVerifyValue"] != null)

            {

                textBoxControl.Text = HttpUtility.HtmlEncode((string)Session["HipControlToVerifyValue"]);

                LabelCodeStatus.Text = "Wrong code";

            }

            Session["HipControlToVerifyValue"] = null;

        }

    }

}

The most important part of the control is to verify the code entered. Since this is stored in a cookie, we retrieve it first and then compare the hashed value of the code with the hashed value stored in the cookie. If the values match we do... nothing. Just let the rest of the page render and do any processing it may need to. However, if values do not match, there's a Response.Redirect to the same page, so rendering and processing of the page stops.

It's certainly a pain if you've just entered an elaborate comment somewhere only to make a typo when you enter the captcha-code, thereby redirecting and losing everything you wrote. So, to make it more friendly, the control has a property “ControlToVerify”. Perhaps the naming is incorrect, but this allows you to store the value of a control, before redirecting and setting the value of the control after the redirect. In this code, it has to be a textbox, but you can change it to anything you like of course.

After all this, you can put the control on any ASP.NET web page, like this:

<%@ Register Src="UserControlHip.ascx" TagName="UserControlHip" TagPrefix="uc1" %>

This Register directive is to be set at the top of the page. The following code is placed at the position you want people to enter the verification code.

<uc1:UserControlHip id="UserControlHip1" runat="server" ControlToVerify="TextBox1"></uc1:UserControlHip> 

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> 

<asp:Button ID="Button1" runat="server" Text="Button" />

That's it. Please add error handling code as you see fit. The rendered image is pretty simple, and you've probably seen more elaborate ones. But I think it'll do the job. If you want to see what it looks like, check out an article, code snippet or news item on DevTips.NET.

You can download a sample project that implements all this here.

Currently rated 3.7 by 25 people

  • Currently 3.72/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET | .NET

Trouble with threads and cultures

by Sander Gerz April 11, 2007 14:19

Here's something that bit me today. A few days ago, a Windows Service I built was redeployed to another machine. Most operations went on just fine, but some didn't. And as always: 'it worked on my machine'. As it had also worked in testing and on the previous production server. After some digging, we found that the regional settings for the service account on this machine were not what they were on the other servers. Yes, I know, don't depend on regional settings, but there was some legacy code (hah..it's not my fault) and it had never created issues before.

So, easy enough, we set the thread for the service to the required culture, like so:

System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("nl-NL");

Unfortunately, it didn't have the desired effect. Nothing changed. As it turns out, you have to set the culture on every thread running. See the sample below:

using System;

using System.Globalization;

using System.Threading;

 

namespace RegionalTime

{

    class ClassDemo

    {

        public static void TimeNow()

        {

            Console.WriteLine("Date setting: {0} ({1})",

                DateTime.Now.ToLongDateString(),

                Thread.CurrentThread.CurrentCulture.DisplayName);

        }

 

        public delegate void TimeNowDelegate();

 

        [STAThread]

        static void Main(string[] args)

        {

            // Look at current regional settings

            TimeNow();

 

            // Switch to French

            Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

            TimeNow();

 

            // Switch to US

            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

            TimeNow();

 

            // Now through a delegate on a different thread.

            TimeNowDelegate methodDelegate = new TimeNowDelegate(TimeNow);

 

            IAsyncResult result = methodDelegate.BeginInvoke(null, null);

 

            while (!result.IsCompleted)

            {

                Thread.Sleep(500);

            }

 

        }

    }

}

As you will see, from running this code, the call through the delegate uses the regional settings from the active user.

Date setting: woensdag 11 april 2007 (Dutch (Netherlands))
Date setting: mercredi 11 avril 2007 (French (France))
Date setting: Wednesday, April 11, 2007 (English (United States))
Date setting: woensdag 11 april 2007 (Dutch (Netherlands))
Press any key to continue . . .

There seems to be no way to specify one culture for the entire AppDomain (note: I'm not talking about ASP.NET here, this was a multithreaded Windows Service). If any thinks or better yet, knows, that this is possible, let me know. I am always eager to learn.

 

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Visual Studio "Orcas" October CTP Available

by Sander Gerz November 01, 2006 08:07

Alex is discussing the September 2006 CTP of Visual Studio “Orcas” and ends with “The next CTP should bring more.”. Well, the next CTP is available. You'll see a number of improvements made compared to the last CTP. Here are a few that peeked my interest.Visual Studio Code Name “Orcas” CTP - Language Integrated Query

  • Enhanced the existing .Net Data Provider to work with the new features in ADO.Net 3.0 such as LINQ and object services;
  • Developers can build can create scripts as actual programs –instead of VBS scripts- that are still completely self-contained in a single file and can be trivially modified, compiled and executed in any environment that has .NET installed.
  • Core functionality of the XLinq API such as load, modify, and save XML documents
  • The current DateTime is insufficient at specifying an exact point in time. DateTimeOffset represents a date time with an offset. It is not meant to be a replacement for DateTime; it should be used in scenarios involving absolute points in time. DateTimeOffset includes most of the functionality of the current DateTime API and allows seamless conversion to DateTime as well.
  • HashSet is a new generic collection that has been added to the System.Collections.Generic namespace. It is an unordered collection that contains unique elements. In addition to the standard collection operations, HashSet provides standard set operations such as union, intersection, and symmetric difference.

It's a good thing these CTP's are made available as a VPC image. After downloading the image (and if you've not done so already, also the base) you only need to run it in Virtual PC or Virtual Server and you're all set.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen | Modified by Mooglegiant