Bill Blogs in C# -- Technology

Bill Blogs in C# -- Technology

Created: 3/28/2012 5:44:21 PM

The next Win8 sample shows the general form of the background task contract for Windows 8 Metro applications.

There are two parts to implementing a background task for a Metro style application: 

  1. Implement the IBackgroundTask interface (contract).
  2. Register the background task with the system so that Windows starts the task at the appropriate time.

The IBackgroundTask interface has only one method: Run().  The only parameter to Run() is an IBackgroundTaskInstance.  Your background task will communicate with the Windows system through the IBackgroundTaskInstance. In this sample, the background task registers to receive the Cancelled event from the IBackgroundTaskInstance if it should stop working on the current problem. The background task also updates the IBackgroundTaskInstance.Progress property to notify the system of its progress on the current problem.

You can think of the IBackgroundTask.Run() method as similar to the Task.Run() method in today's .NET environment: it's the entry point for your background task.

Registering a background task in WinRT is a bit more involved. Remember that this background task is not the same as just running something asynchronously. Instead, these background tasks communicate with the OS, so that they can receive events while your application is suspended. For example, a Mail client will be awakened, check mail, then update its live tile periodically when suspended. That requires using the Windows system Background Task contract.


You register a Background Task in a few steps, using a BackgroundTaskBuilder object. There are several properties you need to set on the BackgroundTaskBuilder:

var builder = new BackgroundTaskBuilder();
builder.Name = name;
builder.TaskEntryPoint = taskEntryPoint;
builder.SetTrigger(trigger);

The name is simply a name you use to identify the task (uniquely) in your application. The TaskEntryPoint is the fully qualified class name for the type that implements IBackgroundTask.

The trigger specifies when the task should be started. Any of the event types you specify must also be specified in you application's package manifest. If you don't specify the event types, your registrations will fail.

Aside: Here the sample seems a bit of a kludgy demo. They trigger some of the tasks when the machine's current TimeZone changes. That, I think, is just for demo purposes. It's easy for you (as the user) to switch time zones, and make the background task start. The other scenarios use a timer, and start the background task every 50 ms. That's closer to a production scenario, but a little short of a time span.

Once you've initialized the builder, you register the task:

BackgroundTaskRegistration task = builder.Register();

That BackgroundTaskRegistration object contains some additional APIs that you use to create and communication channels between your foreground task and your background task.

task.Progress += new BackgroundTaskProgressEventHandler(OnProgress);
task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
 
private void OnCompleted(IBackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e)
{
    //
    // Update the UI with progress reported by the background task.
    //
    SampleDispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
    (task, args) =>
    {
        try
        {
            var taskCompletion = task as IBackgroundTaskRegistration;
            var completionArgs = args.Context as BackgroundTaskCompletedEventArgs;
            if ((taskCompletion != null) && (args != null))
            {
                if (completionArgs.Status != null)
                    throw completionArgs.Status;
                var key = taskCompletion.TaskId.ToString();
                var settings = ApplicationData.Current.LocalSettings;
                switch (taskCompletion.Name)
                {
                    case SampleBackgroundTaskName:
                        SampleBackgroundTaskStatus.Text = settings.Values[key].ToString();
                        break;
                    case SampleBackgroundTaskWithConditionName:
                        SampleBackgroundTaskWithConditionStatus.Text = settings.Values[key].ToString();
                        break;
                    case ServicingCompleteTaskName:
                        ServicingCompleteStatus.Text = settings.Values[key].ToString();
                        break;
                    case TimeTriggeredTaskName:
                        TimeTriggeredBackgroundTaskStatus.Text = settings.Values[key].ToString();
                        break;
                }
            }
        }
        catch (Exception ex)
        {
            Error.Text = ex.ToString();
        }
    },
    sender,
    e);
}
 
private void OnProgress(IBackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs e)
{
    SampleDispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
        (task, args) =>
        {
            var taskRegistration = task as IBackgroundTaskRegistration;
            var progressArgs = args.Context as BackgroundTaskProgressEventArgs;
            if ((task != null) && (args != null))
            {
                switch (taskRegistration.Name)
                {
                    case SampleBackgroundTaskName:
                        SampleBackgroundTaskProgress.Text = "Progress: " + progressArgs.Progress + "%";
                        break;
                    case SampleBackgroundTaskWithConditionName:
                        SampleBackgroundTaskWithConditionProgress.Text = 
                        "Progress: " + progressArgs.Progress + "%";
                        break;
                    case ServicingCompleteTaskName:
                        ServicingCompleteProgress.Text = "Progress: " + progressArgs.Progress + "%";
                        break;
                    case TimeTriggeredTaskName:
                        TimeTriggeredBackgroundTaskProgress.Text = "Progress: " + progressArgs.Progress + "%";
                        break;
                }
            }
        },
        sender,
        e);
    }
}
 
 

Of course, if you can register background tasks, you probably want to unregister them and make them stop.
The sample unregisters the background task by looping through each task and removing the requested task by name:

foreach (var cur in BackgroundTaskRegistration.AllTasks)
{
    if (cur.Value.Name == name)
        cur.Value.Unregister(true);
 
}
 

I'm assuming that you can also unregister the task by using the BackgroundTaskRegistration returned by the original register task call.
The key points to this sample are that there is a contract for Background Tasks that enables the your application to be awakened by Windows to perform some functions in response to time, or system events.

The keys to this sample are that there is a contract you should follow if your application needs to do periodic work while suspended, or running in the background. By following that contract, you’ll find much of the infrastructure you need is built into the operating system.

Created: 3/27/2012 3:23:47 PM

The joint async talks that Jon Skeet and I presented at CodeMash are now live on InfoQ.  Jon and I co-presented two hours of content on the C# 5 async features: Part 1, Part 2.

If you want to experiment with the code (or the slides) while watching, all the samples are here on BitBucket.

Of course, the current VS11 / C# 5 software is a moving target.  When we spoke in January, we were working with a pre-beta CTP of VS 11.  The sample code reflects that drop of the upcoming release.  Jon has written a recent blog post in his EduSync series that describes the changes (some public, some private implementation) between the VS11 preview build and the VS11 Beta build released in March.

Happy async coding!

Created: 3/26/2012 4:25:16 PM

This post is part of my Windows 8 / WInRT exploration and notes.  This time, I’m digesting the WinRT Controls sample.

This sample has quite a few more features to digest. There are six different control scenarios. This application supports landscape, portrait, and snapped orientations. As a result, this post will get longer than my average post.

Screen Orientation Support

Most of the orientation support is provided by the underlying framework. Your application must  respond to the ViewStateChanged event:

Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().ViewStateChanged += 
          new TypedEventHandler
    <Windows.UI.ViewManagement.ApplicationView, Windows.UI.ViewManagement.ApplicationViewStateChangedEventArgs>
    (MainPage_ViewStateChanged);

When you receive this event, you instruct the Visual State Manager to transition to a particular state:


VisualStateManager.GoToState(this, 
    ApplicationView.Value.ToString() + DisplayProperties.ResolutionScale.ToString(), false);

The States must be defined in your main window's XAML description.  Your XAML must include a <VisualStateManager.VisualStateGroups> node.  This element contains a sub-element called VisualStateGroup.  The VisualStateGroup element contains a number of VisualState elements. These elements are named and those names are the states used in the GoToState call above.  Here's en edited version from the Controls sample:

          <
          VisualStateManager.VisualStateGroups
          >
        
          <
          VisualStateGroup
          x:Name
          ="OrientationStates"
          >
        
          <
          VisualState
          x:Name
          ="FullScreenLandscapeScale100Percent"
          />
        
          <
          VisualState
          x:Name
          ="FilledScale100Percent"
          >
        
          <!-- elided -->
        
          </
          VisualState
          >
        
          <
          VisualState
          x:Name
          ="FullScreenPortraitScale100Percent"
          >
        
          <!-- elided -->
        
          </
          VisualState
          >
        
          <
          VisualState
          x:Name
          ="SnappedScale100Percent"
          >
        
          <!-- elided -->
        
          </
          VisualState
          >
        
          <
          VisualState
          x:Name
          ="FullScreenLandscapeScale140Percent"
          >
        
          <!-- elided -->
        
          </
          VisualState
          >
        
          <
          VisualState
          x:Name
          ="FilledScale140Percent"
          />
        
          <
          VisualState
          x:Name
          ="FullScreenPortraitScale140Percent"
          >
        
          <!-- elided -->
        
          </
          VisualState
          >
        
          <
          VisualState
          x:Name
          ="SnappedScale140Percent"
          />
        
          </
          VisualStateGroup
          >
        
          </
          VisualStateManager.VisualStateGroups
          >
        

This application supports eight different visual states.  See the documentation for the ViewStateChanged event for more details.

Once the app is loaded, it runs mostly like a familiar WPF or Silverlight application. There is a control for the list of scenarios.  When you select a different scenario, the main window loads the input and output panes for that scenario.

With only one exception, the scenarios are entirely coded in XAML. Rather than put a lot of declarative XAML in the enntry, I'll point out the big picture concept:

If you have been writing WPF or Silverlight applications at all, the XAML used for the WinRT controls will be completetly familiar to you. Run the application, and you can likely guess exactly what the XAML looks like.
So far, Windows 8 apps look a lot like WPF or Silverlight apps (if you are a C# or VB.NET developer).

Created: 3/13/2012 3:14:41 PM

This post contains my notes from the "File Access" sample in the Windows 8 developer samples.

Let me start by noting that all these samples are designed to show how the API is structured.  These samples do not show proper separation of concerns, or architectural patterns like MVVM. In fact, all the code is in the CodeBehind for the MainWindows.xaml.cs.  Oh well, that's not what the samples are teaching.

There are two key takeaways from this sample.  First, IO programming in WinRT is very similar to IO programming in the .NET Framework. The addition of the 'await' keyword before each call is the only new technique here. Second, Metro applications should not just browse the file system for storage locations.  Each application should restrict its storage to the application specific document library.  The code shows both of these concepts pretty clearly.

The main Window's Initialize() code initializes a StorageFile object by searching for the file on disc, and creating the associated StorageFile object (asynchronously, of course):

async void Initialize()
{
          try
        
    {
        sampleFile = await Windows.Storage.KnownFolders.DocumentsLibrary.GetFileAsync("sample.txt");
    }
          catch (FileNotFoundException)
    {
          // 'sample.txt' doesn't exist so scenario one must be run
        
    }
}

The other file APIs all work in a similar fashion.  Reading a file looks almost exactly like reading a file with the current .NET BCL library:

async void Scenario2ReadText_Click(object sender, RoutedEventArgs e) 
{ 
          if (sampleFile != null) 
    { 
          string fileContent = await FileIO.ReadTextAsync(sampleFile); 
 
          this.Scenario2Output_textblock.Text = "The following text was read from '" + 
 
                sampleFile.Name + "':" + Environment.NewLine + Environment.NewLine + fileContent; 
 
    } 
}

The Streaming APIs are also present, and look quite familiar:

async void Scenario4WriteToStream_Click(object sender, RoutedEventArgs e)
 
{
          if (sampleFile != null)
    {
          string userContent = Scenario4Textbox.Text;
          if (!String.IsNullOrEmpty(userContent))
        {
          using (IRandomAccessStream writeStream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite))
            {
          using (DataWriter dataWriter = new DataWriter(writeStream))
                {
                    dataWriter.WriteString(userContent);
                    await dataWriter.StoreAsync();
                    await dataWriter.FlushAsync();
          this.Scenario4Output_textblock.Text = "The following text was written to '" +
                        sampleFile.Name + "' using a stream:" + Environment.NewLine + Environment.NewLine +
                        userContent;
                }
            }
        }
          else
        
        {
          this.Scenario4Output_textblock.Text =
          "The text box is empty, please write something and then click 'Write' again.";
        }
    }
}
async void Scenario4ReadFromStream_Click(object sender, RoutedEventArgs e)
{
          if (sampleFile != null)
    {
          using (IRandomAccessStream readStream = await sampleFile.OpenAsync(FileAccessMode.Read))
        {
          using (DataReader dataReader = new DataReader(readStream))
            {
          uint numBytesLoaded = await dataReader.LoadAsync((uint)readStream.Size);
          string fileContent = dataReader.ReadString(numBytesLoaded);
          this.Scenario4Output_textblock.Text = "The following text was read from '"
                    + sampleFile.Name + "' using a stream:" + Environment.NewLine + Environment.NewLine + fileContent;
            }
        }
    }
}

I won't simply repost the rest of the code. This is enough to ensure that you get the main ideas.  There are two main ideas to get across from this sample:

1. Store your application's data in the application specific sandbox.

2. Use the familiar IO APIs, but remember that they are async.

Created: 3/12/2012 12:16:14 PM

Now that the Windows 8 Consumer Preview is out, I'm starting a series of blog posts on creating WinRT / Metro applications using C# and XAML.  As with other series I have done in the past, early on, these posts are my raw notes as I work to understand the new developer APIs and libraries.

Like most of you, I'm starting from ground zero learning WinRT. I've been running the Windows 8 Developer Preview since the //build/ conference, and I'm finally getting enough time to explore the developer APIs.  In time, this series should provide a quick and handy notebook toward finding how to solve specific problems using the WinRT platform. In this series, I'm looking at each of the samples you can download here. http://code.msdn.microsoft.com/windowsapps/Windows-8-Modern-Style-App-Samples Specifically, I'll discuss what you can learn from each of the samples. In this first post, I'll disect the Splash Screen Sample.

Why have a Splash Screen Sample at all?

This sample shows a few important rules for Metro apps.  All Metro apps can specify a splash screen resource. The Windows runtime will display that splash screen when the app starts. That's all you need to do if you want the system defined splash screen behavior. Open the package.AppXManifest file in Solution Explorer and define the image to use as the splash screen.

The Application configured Splash Screen will display for a system-defined period of time. Your application should be ready to display its main UI once the splash screen is dismisssed.

There are two important techniques to learn from this sample: How to display an extended splash screen, and how to avoid the need for an extended splash screen.

To display an extended splash screen, your application's startup code must created the extended splash screen, giving it the same coordinates as the system SplashScreen.

SplashScreen splashScreen = args.SplashScreen;
ExtendedSplash eSplash = new ExtendedSplash(splashScreen, false);
          public ExtendedSplash(SplashScreen splashScreen, bool dismissed)
{    
    InitializeComponent();             
          this.splashImageCoordinates = splashScreen.ImageLocation;             
          this.splash = splashScreen;             
          this.dismissed = dismissed;             
          // Position the extended splash screen image in the same location as the splash screen image.    
        
          this.extendedSplashImage.SetValue(Canvas.LeftProperty, this.splashImageCoordinates.X);             
          this.extendedSplashImage.SetValue(Canvas.TopProperty, this.splashImageCoordinates.Y);             
          this.extendedSplashImage.Height = this.splashImageCoordinates.Height;             
          this.extendedSplashImage.Width = this.splashImageCoordinates.Width;             
    LearnMoreButton.Click += new RoutedEventHandler(LearnMoreButton_Click);             
    Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);
}
Once the main splash screen is dismissed, the extended screen will be shown.

The second technique is to use the system SplashScreen's dismissed event to delay some actions, to avoid the need for an extended splash screen at all.

In your application startup code, you register to receive the dismissed event for the splash screen. You can (and should) defer as much work as you can until this event is raised. That enables you to show your UI sooner, and your app will be more fast and fluid.

Created: 3/6/2012 12:33:11 PM

I spent last week at the Microsoft MVP Summit. Among other things, it made me think about the conventional stereotype of the engineer: quiet, introverted, even socially awkward. In the interest of getting more young people interested in the so-called STEM (Science, Technology, Engineering, Math) fields, I want to explode those myths.

The technical content at the MVP summit is all covered under a Non-Disclosure Agreement (NDA); this post will not cover that content. Instead, I’ll focus on the experience. It is pretty typical for a technical conference.

The days were spent learning about new technology and software. The sessions were quite interactive, with attendees holding conversations with presenters throughout the day.  During breaks, we caught up with friends from all over the world. I reconnected with friends from Brazil, Portugal, Austria, Germany, Denmark, Egypt, Australia, India, Korea and Japan. That’s in addition to people from all across the United States and Canada. I met new people at breakfast everyday, and discussed everything from different cultures, to technology, to the customs of places around the world. Lunch was full of discussions with people from around the world that shared the same technology interests.

And then, of course, there was the evenings. I attended packed parties hosted by GitHub, Telerik, and several groups within and associated with Microsoft. Not a single day’s events ended before 12:30 am. We discussed technology, our companies, the people we work with, the economy, politics, family, friends, recent trips, and everything else.

Then, of course, there was the Microsoft hosted party at Century Link field in Seattle. We could tour the sky boxes or  go down to the field. Half the field was set up for the Seahawks; we could throw the football around on an NFL field, or kick field goals.  The other half was setup for the Seattle Sounders Soccer team. You could kick the soccer ball around, including trying to score a penalty kick against their goalie.  Native North Americans explained American football to our International friends. Our international friends from places were soccer is more prevalent explained the nuances to us. I still don’t understand the offsides rule in soccer, but I know a lot more than I did. For those that didn’t want to go on the field, there were bands playing a DJ and a dance floor, and all the restaurants and bars in the stadium were open. Most were full of folks having a great time.

If you take the time to engage in conversations with technical folks, you’ll hear us talk about the various communities we belong to. This is an example of what we mean. As one of the Microsoft MVPs, I’m part of a global community of about 5000 technology professionals around the world. I’m also part of the local Software Developer Community, attending many of the local events for technology professionals. I’ve made lifelong friends in those communities. Far from being introverted and shy, the technology communities I’m part of are the most outgoing and friendly groups of people I know. I ‘d especially encourage young people to look at the reality of the technology community. I think we have more fun, and make more friends, than almost any other profession.

Created: 2/22/2012 10:02:29 PM
This topic came up again in on one of the C# developer mailing lists I participate in.  Because there is still a reasonable amount of confusion on this topic, I thought I would post the rules and the reason behind those rules here. Everything from this post is taken from Sections 7.5.2 (Type Inference) 7.5.3 (Overload Resolution) in the C# Language Specification (4th edition). Consider these two overloads of a Log method:
staticvoid Log<K,V>(K key, V value)
staticvoid Log<K,V>(string key, IDictionary<K, V> values)
Suppose you called it with the following code:
class FooDict : Dictionary<string, int>
{
}
// create custom dictionary
FooDict fooDict = new FooDict();
// should *not* use the IDictionary<K,V>
Log("FooDict", fooDict);
// try a regular dictionary value
Dictionary<string, int> dict = fooDict;
// should *not* use the IDictionary<K,V> 
Log("Dictionary", dict);
// now try the EXACT type
IDictionary<string, int> idict = fooDict;
// should use the IDictionary<K,V> - does
Log("IDictionary", idict);
The comments do explain what happens. But why? Before doing anything else, the compiler searches for all the possible candidate methods for any method call. That list of candidate methods may include generic methods.  If the method call does not specify the type parameters, the compiler must infer them. Eric Lippert’s annotation in the spec is very pertinent here (emphasis his):
The type inference algorithm is designed to answer one question: Given only the arguments and the formal parameter types, what is the best possible type arguments that can be inferred for each type parameter?
In the first case, Log<string, FooDict> is the best possible type arguments that can be inferred. Now we come to the overload resolution algorithm.  There are two candidate methods. Using the inferred type parameters, the first is a better match, because it is an identify conversion: Log<string, FooDict> is an identity conversion from Log<string, FooDict>. In the second case, there is an implicit conversion from Log<string, FooDict> to Log<string, IDictionary<string, int>>, because FooDict implements IDictionary<string, int>. The identity conversion is a better match than a conversion to an interface. The same logic would apply to any implicit conversion: converting to a base type, a widening conversion (e.g. from int to long), or a user defined implicit conversion. It’s one thing to quote the spec and say “this is how it works”, but why is this the right choice for the language?  Briefly, it’s because type inference must work with the actual compile time type of the formal parameters.  I discuss these issues in the C# Puzzlers Live Lessons I just completed.
Created: 2/15/2012 9:00:39 PM

We had an interesting discussion around the office today around this article in the Guardian.  The thesis seems to be that developers should concentrate on the Android platform, even though too many are concentrating on iPhone apps. His justification is two fold: Developers are spending too much time on the wrong platform, and they are doing that because they want to advocate for their preferred platform.

I think that’s an incorrect analysis, for two important reasons.

  1. The Killer App for a Smartphone is the ability to make and receive calls. (Or, if you are under a certain age, to send and receive text messages.) No customer picks a particular phone platform for the apps. The choice of platform is largely made based on the local market, the carrier coverage, brand image, and what phone platforms are available and pushed by the carrier (at least in the US)
  2. The number of available Apps affects the buying decision in two ways, and neither is a linear relationship. If there are ‘enough’ apps, the platform can be competitive. The three major platforms discussed in the article, Android, iPhone, and Windows Phone, all have enough apps to be competitive. Beyond a certain point, app numbers only add confusion to the marketplace. I mean, really, how many weather apps do you want to sift through?

That means Developers can drive a platform market only to a point. Once there are enough apps, more or less developer participation won’t matter. I do believe developers themselves know this as well. I don’t think any software developer is creating iPhone apps because they want iPhone to win more marketshare.

My concern about the article is that business people may walk away from it with a simple answer of “Write for Android”. I don’t believe the market is that simple. I don’t think that’s smart.

We encourage our customers interested in mobile apps to target both Android and iPhone. Together, they are 65% of the market. After that, adding a third (or more) platforms produces diminishing returns. That’s because both the third and fourth platforms (by market share) are shrinking: Symbian and RIM. I would not advise a customer to develop a new app for a shrinking market.

Windows Phone 7 is interesting if your app would benefit from one of two factors. There are fewer apps there, so you may be able to stand out better. Or, if your app space has a deep integration with the Microsoft ecosystem, it’s a smart bet. Otherwise, it’s still too small to be a first or second choice.

Finally, there’s the HTML5 path. I think that’s fine if your application’s purpose is to be a cross-platform app. That, to me, means an app that gets sold in the enterprise, and all the users will be trained on the app, and the users will prefer a consistent experience even when that experience is not the best for that particular platform. If your application must compete against native apps on any of the major platform, and least common denominator solution will likely fall behind.

My recommendations are not a simple sentence, because I don’t think it’s that simple. If you really want to make a smart decision about a mobile strategy, it takes more than just one data point, like market share of that platform. You have to understand how your market intersects with the platform market, the costs of actually supporting each additional platform, and the competition in the app space on each platform.

Created: 2/14/2012 7:35:44 PM

We often help our customers update their software development environments to more modern practices.  Sometimes this involves languages and frameworks. Other times it involves updating a classic waterfall process with many of the practices from the lean and agile communities. At still other times, it involves an investment in the user experience.

This particular post is about introducing modern software development techniques, including scrum, into a large organization. I’ve been noticing how much the concerns and the values change as what we do becomes more and move visible to larger and larger parts of the organization.

Our first projects were small (for an enterprise organization). The stakeholders were key members of the user community, and maybe first or second level managers. Our scrum process worked quite well, and we had good success. The stakeholders understood the core values of our project: Let’s build useful software in a timely fashion. Everything else supported that goal. We wrote only enough documentation to support building software. Most (almost all) of the testing was automated. The automated tests were the test plan.

The projects were successful. Our stakeholders showed their management that our projects all achieved great ROI, and we showed a much better on time track record than their traditional process.

That was great, until it wasn’t.

See, we were successful. But, we weren’t ‘following the corporate standard.’ As more and more new managers and new departments were involved, the priorities changed. That core value of “building useful software in a timely fashion” was replaced by a core value of “following the process”.

I have to admit, following a waterfall process is seductive. It 'looks like you can accurately predict the future. You spec things, you build schedules, you ‘follow the plan’. Unfortunately, software projects (and real life) are not like that. No plan survives contact with reality.  But, until those fallacies are exposed, the illusion is powerful. “These other teams have a plan. They’re organized. They’re following the process.”

My theory on why this happens is this: The farther removed a manager in a large enterprise actually is from a project, the more their goal shifts from the project actually succeeding to not being responsible. The enterprise process models, in my opinion, make that easier. The team no longer ‘owns’ the success or failure of the project. The team ‘owns’ adherence to the process.

I hope that data, such as this provided by Mike Cohn, can help. Will the same people swayed by “THE PROCESS” by swayed by “THE DATA”?  (Read the comments on Mike’s post, he does discuss some of the industry’s concern with Standish reports.) 

I hate writing just ‘downer’ posts, so I must close with some wisdom from Mary & Tom Poppendieck. Whenever we find ourselves in one of these situations, we look at Principle 7 from “Implementing Lean Software Development: From Concept to Cash”:  Optimize the Whole. Process has some place. and some communication is valuable. However, too much process means not optimizing the whole, and not delivering great software. We keep reminding our stakeholders that the point isn’t to have a pretty plan. It’s to have working software sooner. Some get it. They hopefully keep pulling others along.

Created: 2/7/2012 4:16:33 PM
We experienced a great example of the efficiency of self-organizing teams last Friday. We’ve been in the same offices for several years now, and like many tech people we’ve started to accumulate aging tech equipment, and other stuff just lying around. That’s in addition to all the normal stuff that any business accumulates. It was time to reorganize the physical space. We allocated last Friday afternoon to finding a place for everything and putting everything in its place. There was very little pre-planning. Dianne Marsh and I made two specific recommendations: We were moving the bookcases into one office, and mounting a 42” TV / monitor on the wall in the library. Everything else was organized by the team. Our developers, our office manager, our sales and operations staff all pitched in. Everyone looked at where they could best help, took on tasks, and got things done. By the end of the day, all the clutter was stored in closets (neatly). All the equipment was in one space. The TV was on the wall, the bookcases were moved. The books are on the bookcases, totally organized. No single person was in charge of the process. Everyone made decisions, and then communicated those decisions to others.

What can we learn from this to apply to other activities?

If you want to experience the satisfaction and the efficiency of self-organizing teams, I think there are a few lessons to draw from this example. First of all, the goal was clearly stated: We need to more efficiently use our space or people. We’ve been consistently growing over the past several years, and if we are too cluttered, there’s not enough room for people. Everything in the office must be neat so we’re ready for customers or colleagues to visit at any time. A secondary goal was to know what we had in the office so we don’t unnecessarily buy more equipment. (I swear cables spontaneously divide and reproduce when left lying around.) Second, don’t limit people’s contributions. We made very few decisions for others. As long as everything got put in a place that worked, we made no restrictions on how any problem got solved. Any group or individual was empowered to find a place and an organization for anything they found that was taking up space. Third, positive peer pressure. We were all working together. No one could say they were doing something more pressing and skip out on the cleaning tasks.  I honestly think nothing destroys team dynamics more than some tasks are ‘beneath’ them. The end result from Friday is great. People have space to work individually, spaces to collaborate. We don’t have to move monitors and cables in order to find space at a desk. And everyone had a hand in it. The more experience we get with Self-Organizing teams, the more impressed we are. You should try to experience it yourself.
Created: 1/19/2012 1:53:15 PM

My video series “C# Puzzlers” is live on both Safari and Inform IT.

C# Puzzlers are a series of small puzzles that make you think about some specific facet of the C# language. I put together a series of exercises are several different facets of the language. I think it’s an engaging way to get your mind around some of the areas of the language that commonly cause confusion for developers.

You can get the puzzlers at InformIT, or Safari.

Created: 1/17/2012 9:44:16 PM

While at CodeMash last week, both BBC and ZDNet published stories about the use of booth babes (BBC’s term) at conferences.

We don’t hire models for our booth at conferences, and we’re not going to.

TLDR version: It would misrepresent our company.

OK, if you’re still with me, here’s the lengthy version.

Problem 1: It gives the wrong impression about the company image.

This is the most important issue. We’ve got a great workplace with mutual respect among all our employees, male and female. Hiring models for a conference booth sends messages, subtle and not so subtle, about our company’s attitudes toward the roles of men and women in our business, and our company. Close your eyes and imagine a female software developer at GoDaddy. Their ad campaigns have affected your impression, and probably not in a good way.

When you execute a marketing or advertising campaign, you must live with the impression you’ve created. You don’t get to say “No, no, that’s not really us. We just did that to get your attention.” You’ve created an image, and you’ve associated that image with your company. Your prospects (as customers, colleagues, or employees) form their image of your company, your culture and your values based on the tools and images you use in your marketing and advertising campaigns.

If that image is not correct, you must work doubly hard to correct it. You must not only continue to build your positive brand image, you must live down the negative impression you’ve cultivated. It’s hard enough work telling the world how great you are. Don’t sabotage it by telling the world how bad you are.

The obvious reason we don’t use models at conferences is that it’s wrong for us. It works against our culture, our values, and the professionals (both women and men) that work here.  For the same reason, we don’t use models on our website. The photos that you appear are people who work at SRT, either now, or in the past, when the photos were taken. But, this is the part where some marketing professional usually says, “I agree, but it works. We’ll do it anyway.”  So let’s move on to why I believe it doesn’t even work.

Problem 2: The increased traffic does not indicate increased interest in your business. It indicates increased interest in models.

Suppose there are 75 people at a 1000 person conference who may be interested in what we do. Our goal, as a business, is to maximize the quality time someone spends talking with those 75 people. Nothing else really matters to the business as a whole.

One serious challenge is that you don’t know who those 75 people are. Standard marketing logic says that if you get the highest number of people stopping by your booth, you’ll get the highest number of possible prospects. That may be true in certain markets, and at certain conferences, but I don’t think it applies all the time.

Suppose we hired models to work at our booth. I have no doubt that we would have more traffic. There would be, however, two problems: First of all, a lot of that increased traffic would not be there because of what we do as a company. The additional visitors would be interested in the models. They are probably not in that 75 attendees I mentioned earlier that are actually good prospects. All the models have done is increase bad traffic and make it harder to spot and have real conversations with the real prospects in the crowd.

Problem 3: It drives away people actually interested in your business.

I’ve said nothing about the makeup of the 75 attendees actually interested in us. How many may be women that are turned off by a marketing strategy right out of “Mad Men”? How many, men or women, would be turned off by that image? How many might be interested in a deeper conversation about software development than they would be likely to have with a model?[1] Would they visit, or would they avoid the booth entirely? Real prospects may decide there’s too much traffic, and just ignore it altogether.

So what will you see at our booth?

We will demonstrate something interesting about us and our thoughts on software development. This last week at CodeMash, we demoed an original game built using the Microsoft Kinect. We did that because we believe there are interesting opportunities to use the Kinect in many applications; it’s important for us to demonstrate that we are already learning this. That’s a key part of the message: Our company stays at the forefront of technology trends, and is often even ahead of our markets. Our technical employees are given time to investigate these new ideas and build software that shows the result of these investigations.

In years past, we’ve shown mobile applications, cloud based applications, and a game controlled by the wii remotes. I don’t know what we’ll build next year. We’re still planning that.

Everyone at our booth works for SRT Solutions. Depending on the conference, they may have a more technical role (like at CodeMash), or a more business oriented role. It depends on the audience, and the conversations that will likely occur. Anyone you see at the our booth represents the company with their knowledge and their professionalism.

You’ll see people dressed pretty much like a normal work day. In fact, if anyone asks for guidance, we’ll say “dress the way you would to attend a customer meeting.” That’s consistent with our culture and our values. And, it’s the same advice regardless of the questioner’s gender.

Do I have a point?

Personally, I believe that the way you market yourself, or your company, is about more than simply generating a high number of leads. Your marketing creates an image of your company. If you’re successful, your marketing imparts that image to many different prospects: customers, partners, employees, and more. You don’t want to live down a marketing campaign that is at odds with your company culture. You’ll attract too many of the wrong prospects, and too few of the right ones. There’s the common phrase that says “half of all your marketing is wasted, you just don’t know which half.” If your marketing is at odds with your values, the sad fact is that all your marketing is wasted.

[1] This is not to say that models are not smart. I’m just saying they know less about software development, and our business, than our employees.

Created: 1/16/2012 5:03:46 PM

While at CodeMash, I had an interesting conversation with Cori Drew regarding some code in Effective C#, and some comments from Jon Skeet in our combined async talks. These comments involve breaking some common recommendations, and performance.

In our talk, Jon described how the C# compiler creates a mutable struct when it builds the state machine that handles async continuations. Jon discussed that the nested struct was faster than a nested class. Contrast that with code in Effective C#, where I showed the following code:

        public
        class List<T> : IEnumerable<T>
{
privateclass Enumerator<T> : IEnumerator<T>
{
// elided
}

public IEnumerator<T> GetEnumerator()
{
returnnew Enumerator<T>();
}

IEnumerator IEnumerable.GetEnumerator()
{
returnnew Enumerator<T>();
}
}

Well, Cori asked, why didn’t I make the Enumerator<T> a struct (which is what the BCL does):

        public
        class List<T> : IEnumerable<T>
{
privatestruct Enumerator<T> : IEnumerator<T>
{
// elided
}

public IEnumerator<T> GetEnumerator()
{
returnnew Enumerator<T>();
}

IEnumerator IEnumerable.GetEnumerator()
{
returnnew Enumerator<T>();
}
}

So, why didn’t I?

Well, as Eric Lippert points out, “mutable value types are evil.”  In general, you should avoid mutable structs. If your type requires mutation to work properly, you should use a reference type. Implementing IEnumerator requires mutation (keeping track of the current item), so you should use a reference (class) type. Unless you are really sure that you need a struct, you should use a class for any type that supports mutating operations.

Because of that, I chose to demonstrate with a class rather than a struct. I felt it would be too likely for readers to copy the code and use it in different situations where the special circumstances that are in play in both async state machines and the nested List iteration are no longer true. I chose to give up some performance in return for a more general idiom that would be correct in more situations.

Given that, let’s discuss why the mutable struct works in these two situations.

In the case of the nested Enumerator class, it’s because of one of the rules for converting a struct to an interface type. When a struct is converted to an interface, it isn’t actually unboxed. The box implements the interface, and adapts the methods defined on the interface by forwarding them to the struct in the box. The struct does not get unboxed and copied on each function call. See Section 11.3.5 of the C# spec for details. Read the following guidance carefully:

If your struct will always be accessed through an interface pointer, that struct can be safely mutable because it will never be unboxed.

The nested private Enumerator satisfies this requirement. It is a nested private type, so that other code cannot access it through the struct value. Client code can only access it through the interface reference, and therefore, the above rule always applies.

The nested structure that implements the state machine in an async scenario also follows a similar pattern, and therefore is safe.

OK, before you go just applying this rule to structs in your programs, read that guideline again carefully. Notice the strong ‘always’ and ‘never’. There can be no exceptions. In the case of the nested enumerator, this is enforced by the fact that GetEnumerator() returns the interface, not the struct. In the case of the nested struct in the async state machine, it’s enforced because it’s in compiler generated code.

You’re probably not so lucky. Chances are you work with other developers. Someday, someone will make some changes to your code so that one of those rules will be broken. Then, bugs will start to crop up.

Even if you are completely sure that those rules will never be violated, take care. Just because you can get away with something safely doesn’t mean you should turn away from normal guidance. In both these cases, the performance gains by changing from a class to a struct, can be significant. That significant performance gain coupled with the guaranteed safety does mean that its worth breaking the normal guidance.

In the case of the nested Enumerable, the performance gains come from the fact that this code will execute very often over the course of many programs.

In the case of the asyn methods, it’s because the team wants to optimize the ‘hot’ path for async methods. The reason is that you (and me) should prefer making a method async if there is a possibility that it will take enough time to warrant it. We shouldn’t worry that declaring a method async will cause an undo performance burden over its synchronous counterpart. With that in mind, the team is working very hard to optimize those code paths.

If you want to switch from a class to a struct, you should perform some measurements and make sure that the change will actually give you the increased performance you seek.

In the end, the same old advice often holds true: Make it work well. Then, once you’ve measured and determined that performance for a given location is critically important, make the changes necessary to achieve those goals. In my books, I wanted to try hard to write general guidance, and I avoided most performance based guidance. It seemed safer than trying to ensure that readers would remember all the specific rules for a particular optimization.

Created: 1/3/2012 1:34:07 PM

For most people, the holiday season is over, but here, where Michigan and Ohio meet, there is one more major event:  CodeMash.

I have not yet figured out my entire schedule, but there’s a few things I plan to concentrate on.  I need to learn more about WinRT. I’ve had too little time to build samples and learn about it yet. I want to learn more about Scala, an exciting functional style language that runs on the JVM. Beyond those specific goals, I want to learn about techniques I can apply across any platform. I don’t believe I’ve learned as much as I can about modern software engineering techniques: testing, continuous improvement, advances in languages, frameworks, and libraries. I want to spend as much time as possible in sessions that are not platform specific, or language specific.

I am giving two different talks this year.  Early Friday afternoon, I have “C# Stunt Coding: I Dare You to Try This at Home” This is a really fun talk to give. I get to start by saying that all the techniques I’m explaining are for edge cases, and specific problems, so chances are you will rarely want to use them in your everyday coding activities. Of course, that means everyone will pay careful attention, and immediately try everything I show the very next day. There’s no avoiding it. Developers just think that way. That makes it more fun.

Spoiler Alert

Ok, not really.

The other talk I have is “Async From the Outside”, where I discuss how the new async programming model in C# 5 introduces new ways to to make async programming easier.  You may have noticed that the abstract for Async From the Outside references the talk “Async From the Inside”, given by Jon Skeet, author of the very popular and respected “C# In Depth”. If you look at the abstract for Async from the Inside, you’ll see it references Async From the Outside.

There’s a few more items you should notice about these two talks:

  • They are in the same room
  • The second (inside) immediately follows the first (outside)

You may be thinking that it would be better to mash these two talks together, giving attendees two hours of async inside and out.

Well, Jon and I thought the same thing. We’re working together on a single stream of content, with both of us working together for the duration of the two talks. We’ll discuss how to use a feature, how it’s implemented, and how to use it in your regular development activities.

Well CodeMash fans, this will be the first time Jon and I have met in person. We’ve emailed, chatted, skyped, google talked, and been on .NET Rocks together, but we’ve never yet met in person. I’m looking forward to it. Jon and I are working quite diligently to make sure we deliver quality content. 

Jon also has his own individual talk to give: C#’s Greatest Mistakes. I’m really looking forward to that one as well.  Jon has shared some of the content with me. He’s one of a very small set of people that can give a talk like this, and make it a great talk for people to learn, not a screed. It’s one of Jon’s best qualities: the skill to be critical, yet positive.

Jon has written a similar post on CodeMash.

Created: 12/19/2011 8:01:07 PM

Dianne Marsh and I have been doing some planning for our expected growth. We will be doing more announcements during the course of the next year.

Right now, we’ve got an immediate opening for a business development associate. (I know that most of my readers are developers, so please pass this on, if you know someone interested in joining us in this capacity).

Of course, we are always interested in talking to exceptional developers about our ongoing growth plans as well.

You can read more here.

I promise: the next posts will have the technical content most of my readers prefer.

Current Projects

I create content for .NET Core. My work appears in the .NET Core documentation site. I'm primarily responsible for the section that will help you learn C#.

All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.

I'm also the president of Humanitarian Toolbox. We build Open Source software that supports Humanitarian Disaster Relief efforts. We'd appreciate any help you can give to our projects. Look at our GitHub home page to see a list of our current projects. See what interests you, and dive in.

Or, if you have a group of volunteers, talk to us about hosting a codeathon event.