Bill Blogs in C# -- .NET General

Bill Blogs in C# -- .NET General

Created: 9/15/2011 4:38:44 PM

I must preface this post. There are more than 10 concurrent sessions in each slot, and obviously I’ve only seen one in each session. I also picked my sessions based on my perspective as a .NET / C# developer.

I’m actually very pleased with what I saw today about the WinRT APIs and the C# language.

Windows RT: A Modern Windows API

Let’s start at the WinRT layer. Currently, the base Windows API is Win32. That API dates back to 1995. In fact, the Win32 API was based on and consistent with the Win 16 API, which means its design is even older. Its design dates back to a day when C++ (and other object oriented languages) were not very popular. It also dates back to a time when the concept of having a computer attached to the internet whenever it was on was unthinkable. It’s also an API that has grown considerably over the last decade and a half. New features and capabilities have been added with each successive release of Windows.

The Windows Runtime (WinRT) represents a redesign of the entire API surface for windows. Throughout the day, I heard three phrases repeated from presenters discussing this new API:

  • decreased surface area
  • consistent view of the system across languages
  • Consistent guidelines for API across all Windows functions
  • A modern object oriented API

I believe the WinRT team redesigned the Windows API from first principles, and created a modern API for the Windows system. It should be easier to use, and simpler for developers to understand.

Accessible from many languages

The next layer up has some very interesting engineering capabilities. Most importantly, the new WinRT layer provides a projection of its API to managed languages. That’s critically important because it addresses a long-standing frustration for managed language developers: New OS features would be released, and those new new features were not accessible from the managed languages without developers creating their own managed wrappers on top of the new native APIs. With Windows 8 and WinRT, managed developers will see new features in projections for their language as soon as those features are available in the OS release. That lag between OS feature and its presence in the managed APIs should go away in this next release. Note these new features will also be immediately surfaced in javascript as well.

That means languages such as C# and VB.NET will immediately have access in their own natural syntax to any new features available in the OS.

In addition, the next version of the C# compiler (and the VB.NET compiler) can produce WinRT components. The projection infrastructure is already there, and if you desire, you can expose your current class libraries (almost certainly after some work to make them conform to WinRT standards). C# is a first class language for WinRT development, just like C++.

The costs

Of course, nothing is free. If you want to participate in this new world, you must conform to the new WinRT standards, and possible leverage newer capabilities, and replace some code.

Some of the .NET APIs are changing for WinRT. I don’t have an exhaustive list, and I’m not sure there is one yet. Other APIs are not exposed via WinRT. (They are still available as .net APIs, just not as Metro / WinRT APIs.)

In the build we got, .NET apps will run in the classic Win7 desktop. It appears that all class libraries (that don’t rely on the Win32 APIs) will run in either environment. I’m not sure about that.

In Metro, the CLR runs on top of the WinRT layer. Just like today, where the CLR runs on top of the Win32 layer. There’s really not a lot of painful change here.  Think about how thrilled you would be if you could write C# code that ran on other devices (like the iOS or droid platforms). if you think of WinRT that way, this makes sense: C# runs on both the win32 stack, and the new WInRT stack.

Some Q & A

caveats: I’m still trying to figure this out myself, and I’m sure I’ve got some of this wrong. It represents my current understanding:

Are .NET applications legacy applications?

Well, sort of. The Metro UI is a different UI paradigm. If your using the current Win32 controls (which includes WPF controls), your application will look really dated in Metro. The only way to fix that is to re-implement the UI (your View classes in an MVVM design) using Metro controls. However, C# and majority of the .NET APIs are first class citizens in this new environment. The rest of your application should be fine.

caveat: WinRT has new network APIs and File System APIs. You may also have to change some logic at your persistence layer.

Is .NET Dead?

As a marketing brand, probably. However, C#, VB, F# and other managed languages are continuing just as strong as before.

Why is HTML5/Javascript and C++ getting so much more attention?

I think that’s just because there’s a bigger story there. C++ has a new standard (C++, The Spinal Tap Edition: It goes to 11). And the tools for building modern windows applications with either C++ or Javascript have gotten much better.

It’s a good story for the platform. C# apps are as well supported as before. It’s just not as interesting of a story.

What about the future of the current Windows Desktop?

I don’t know. I’ve only had the build tablet for a day, and it’s a different experience. It’s pleasant for many tasks, but for others, I prefer a keyboard and the classic desktop. That may change as time goes on. And that will have a great bearing on how this evolves in the future.

My guess:  “desktop” apps will run fullscreen in a private ‘virtual desktop’ in the future.

Recommendations

You should recognize that the Metro UI represents a rather large sea change in what makes a great application in Windows. If you ignore it, your applications will start looking dated.

However, this doesn’t mean you should rewrite your applications in WinRT. At least not yet. However, I would think carefully about what your application would look like in Metro. Is there a great Metro experience for your app? If so, start that migration.

Of course, some standard recommendations still apply: If you separate the layers of your application, it will be much easier to preserve large parts of your application as it moves to Metro. Regardless of your plans moving forward, that would be a good practice.

We do live in interesting times.

Created: 7/11/2011 2:47:06 PM

I interrupt my normal tech content for an event announcement.

I’m happy to announce that Paul Sheriff is coming to Ann Arbor to teach his one day “Zero to Silverlight” training. The event will be held on Tuesday, August 30th, at SPARK Central in Ann Arbor. Paul is a recognized leader in the Silverlight and Windows Phone communities.

You can learn more about the event here.  You can register here. (Early bird discounts are available until July 31).

I hope to see you there.

Created: 6/15/2011 5:48:03 PM

I’m now at that point where I’m blogging about others’ accomplishments. And I’m thrilled.

Chris Marinos SRT’s resident F# guy is giving his Getting your Func(tional) on with F# talk at the New York City F# Meetup Group tomorrow (June 16th). He’s given that talk in our office as a practice session, and it’s a great way to learn more about F#.

If that’s not enough, Don Syme, the inventor of F# is helping to promote the talk here.

I’m glad that we’ve got such a great group of software engineers, and those people are starting to get noticed on a national stage.

Created: 6/9/2011 3:56:26 PM

Last week, Microsoft took the wraps off the new Windows 8 shell. Predictably, the internet has been filled with opinions and predictions.  I may as well add mine.

What we saw

I am very impressed with the new UI, the immersive nature of Metro style apps, the consistency between the phone and desktop UIs, all of it. There are three arguments in favor of the new presentation model:

It’s time: While there have been several improvements and refinements over time, the current shell is fundamentally similar to Windows 95. Revolutionary in its day, that was 15 years ago. Desktops were more prevalent that laptops. Tablets were primarily a research toy, not a production device. The term “Smart Phone” didn’t exist. The idea of connecting a TV to the internet made no sense.

Consumers (whether for business or personal use) have very different expectations than they did back then.

Consistency: Consistent user experience is very important. It enables users to leverage what they’ve learned in one application (or device) and apply it to new experiences. That doesn’t necessarily mean having identical experiences everywhere, but it does mean having a consistent experience everywhere.

Consumers want to leverage the same skills whether they are using a phone, tablet, desktop/laptop, surface, or TV screen.

But not identical: Having said that, I don’t see myself using a phone, a tablet, or my TV as my primary developer machine. The laptop is a much better choice. I want to type; I want a larger screen. I may even open a command shell. That means even though consistency is important, maybe even critical, respecting some differences that enables each device to utilize its own features best is also important.

The experience must enable applications (or apps) to leverage the particular capabilities of the device the user has right now.

Is this the right experience? Based on what I’ve seen so far, yes it is. It maximizes the screen real estate for an application, while minimizing the OS chrome of years gone by. It respects that fact that users will have several apps running, but will likely be giving one app the major focus.

Speculation for Developers

I’ve said nothing about the developer story. I really don’t know. You’ve undoubtedly heard discussions around C++ (or WinC++), and HTML5/JavaScript. Those technologies make sense, for different reasons.

C++ still has a larger developer community that any other programming language on the planet. With so much emphasis on .NET and managed code, the market seemed to forget that Microsoft has one of the major C++ compilers, and produces many familiar windows applications.

HTML5 and JavaScript are the hot new technologies, and are receiving tremendous buzz. Microsoft cannot ignore them, and it’s smart to announce support for them in the next version of Windows as early as possible.

It’s hard not to speculate and extrapolate on what those announcements mean. I want to defer that, because we really don’t know. But, I’ve been asked too many questions. What follows is pure opinion.

Personally, I don’t believe that .NET, C#, VB.NET, or managed code are going away, losing support, or even being pushed to the back seat. Those communities are too big, and they all have too many options to migrate if they do really feel that Microsoft abandoned them.

I didn’t mention Silverlight or WPF, because my opinion is that they will change. The new Metro-based shell is very different than the current Windows shell. It’s got different capabilities, different features, and will require different APIs. It’s reasonable to think that a new library for that new shell will look different. It’s a naming decision if it’s a new version of Silverlight, or WPF, or a new XAML based library. I do believe there will be a managed library that will enable developers to target the new shell on Windows 8.

I headed this section "Speculation” because these are my own opinions. I’ve heard nothing under NDA about the developer story around Windows 8. A search for “Microsoft” and the codename “Jupiter” gives you some of the resources for my thoughts.

Until there’s more announcements, that’s all we have. I expect to learn more at the Build Windows conference.

Created: 5/19/2011 5:58:42 PM

Then install PerfWatson.

Briefly, PerfWatson is a diagnostic tool that Microsoft released that helps the Visual Studio team diagnose, and then alleviate performance bottlenecks in Visual Studio. It is an addon to Visual Studio. It detects when the UI has become unresponsive, collects data on performance issues, and sends that data (with your approval) so that the team can improve Visual Studio performance.

You can learn about PerfWatson here.

You can install it directly here.

Created: 5/12/2011 3:47:01 PM

I’m thrilled to announce another event in the SRT Software Development Series.

Paul Sheriff, a fellow Regional Director, and author of an immense amount of developer content, is coming to Ann Arbor for a one day class on Silverlight. “From Zero to Silverlight” teaches developers the fundamentals of Silverlight, and gets them started on the road to being highly productive Silverlight developers.

This class will be held on June 7th, at SPARK Central, just a block from SRT Solutions.

If you’re interested in becoming a better Silverlight developer, or you’re interested in being a Silverlight developer, you need to attend this class. Learn more, and sign up here.

Created: 5/11/2011 6:56:38 PM

Let’s keep up that async momentum.  It’s time to explore another set of Lucian’s online async samples. This time, it’s about expressions around an await.

The key concept here is you can substitute ‘await <SomeExpression>’ anywhere ‘<SomeExpression>’ is valid. The result of an await expression can be used anywhere that expression could be used.

For example, you can invoke members of the expression being awaited:

        public async void AsyncMemberAccessAround()
{
Console.WriteLine("Content length:");
Console.WriteLine(
(await new WebClient().DownloadStringTaskAsync
(new Uri("http://www.weather.gov")))
.Length);
}

Notice that the ‘.Length’ is a member of the expression ‘await new WebClient()..’. The asynchronous result has a Length property because the operation’s result has a Length property.

Similar to the last set of samples, Lucian runs through all the operators.  Some are particularly interesting, and I discuss those below:

If your async operation returns an Action or Func, you can invoke it when it is available:

        public async void AsyncInvocationAround()
{
Console.WriteLine((await PrecalculateCosineTableAsync())(0.0));
}

public async Task<Func<double, double>> PrecalculateCosineTableAsync()
{
await new SynchronizationContext().SwitchTo();

Thread.Sleep(1000); // Simulate precalculating a table of cosine values

return d =>
{
if (d == 0.0) return 1.0;
elsethrownew NotSupportedException();
};
}

The usual conversion operations behave as though the operation was synchronous:

ublic async void AsyncAsAround()
{
string str = await DeserializeAsync() asstring;
if (str != null)
{
Console.WriteLine(str);
}
else
{
Console.WriteLine("Deserialization failed.");
}
}

public async Task<object> DeserializeAsync()
{
await TaskEx.Delay(200); // Simulate loading an object from disk and deserializing it
return"serialized string";
}

Lucian also wrote several samples that generate numeric results. Those samples show that you can perform the usual mathematical operations on results that will be delivered in the future. Addition is one example:

        public async void AsyncBinaryMinusAround()
{
Console.WriteLine(await LongRunningOperation() - 5);
}

public async Task<int> LongRunningOperation()
{
Console.WriteLine("Attempting long-running operation...");

await new SynchronizationContext().SwitchTo();

// Simulate a process that takes between 2 and 4 seconds to complete.
Random r = new Random();
await TaskEx.Delay(r.Next(2000, 4000));

return 123;
}

Once again, the key lesson to learn from this set of samples is the integration of the async pattern into the familiar idioms of the C# language. That makes it easier to integrate the async pattern into your regular programming.

Created: 4/18/2011 12:16:09 PM

The next set of Async samples shows how the await keyword integrates into the familiar control flow constructs in the C# language. There are seven different samples in this section, and I won’t show all of them. Again, I’ll encourage you to visit Lucian’s site and try them yourself.

The first sample in this set clearly illustrates the advantages of the new syntax. The version using await enables you to see the branching logic easily:

        public async void AsyncIfElse()
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday ||
DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
{
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/om/marine/home.htm")));
Console.WriteLine("It's the weekend! Time for the marine forecast!");
}
else
{
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov")));
Console.WriteLine("Back to work!");
}

WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/forecasts/graphical/")));
Console.WriteLine("Always useful to get a general forecast!");
}

Notice that await appears in the if branch, the else branch, and toward the end of the method. This will await the result of each of those actions, as you’ve seen in previous blog entries.

Contrast the clarity of the method above with the equivalent code using C# 4.0 syntax:

        public
        void AsyncIfElseBefore()
{
WebClient client = new WebClient();

if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday ||
DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
{
client.DownloadStringCompleted +=
AsyncIfElseBefore_Weekend_DownloadStringCompleted;
client.DownloadStringAsync(
new Uri("http://www.weather.gov/om/marine/home.htm"));
}
else
{
client.DownloadStringCompleted +=
AsyncIfElseBefore_Weekday_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://www.weather.gov"));
}
}

void AsyncIfElseBefore_Weekend_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
WriteLinePageTitle(e.Result);

Console.WriteLine("It's the weekend! Time for the marine forecast!");

AsyncIfElseBefore_GeneralForecast();
}

void AsyncIfElseBefore_Weekday_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
WriteLinePageTitle(e.Result);

Console.WriteLine("Back to work!");

AsyncIfElseBefore_GeneralForecast();
}

void AsyncIfElseBefore_GeneralForecast()
{
WebClient client = new WebClient();

client.DownloadStringCompleted +=
AsyncIfElseBefore_GeneralForecast_DownloadStringCompleted;
client.DownloadStringAsync(
new Uri("http://www.weather.gov/forecasts/graphical/"));
}

void AsyncIfElseBefore_GeneralForecast_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
WriteLinePageTitle(e.Result);

Console.WriteLine("Always useful to get a general forecast!");
}

Ok, this version is obviously much longer. More than that, the original control flow gets lots among all the event handlers. One simple method suddenly grew to five  methods that connect and weave continuations to the original tasks. This sample, more than any other in this set shows how the new syntax makes it easier to write asynchronous code and still preserve the core logic of the original algorithm.

I’ll show two other samples.  The first shows a method with a switch statement. And inside each case of the switch statement, the method awaits. That means the entire method is async:

        public async void AsyncSwitch()
{
double stockPrice = 123.45;

switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/wa.php?x=1")));
stockPrice += 1.25;
break;
case DayOfWeek.Tuesday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/or.php?x=1")));
stockPrice *= 1.04;
break;
case DayOfWeek.Wednesday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/ca.php?x=1")));
stockPrice -= 0.58;
break;
case DayOfWeek.Thursday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/nv.php?x=1")));
stockPrice *= 0.99;
break;
case DayOfWeek.Friday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/az.php?x=1")));
stockPrice += 0.79;
break;
case DayOfWeek.Saturday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/ut.php?x=1")));
stockPrice += 1.8;
break;
case DayOfWeek.Sunday:
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/alerts-beta/nm.php?x=1")));
stockPrice /= 1.2;
break;
}

Console.WriteLine("Today's stock price: {0}", stockPrice);
}

If there is an await in the method, the entire method is async.

The last note is that Task, and Task<T>, implement IDisposable, therefore, and await expression can be the body of a using statement:

        public async void AsyncUsing()
{
using (var response = await WebRequest.Create(
"http://www.weather.gov").GetResponseAsync())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
WriteLinePageTitle(await reader.ReadToEndAsync());
}
}

Remember that tasks implement IDisposable, clean them up.

The elided samples show that await can be placed almost anywhere among the different control flow elements of C# (for, if / else, while, foreach, and so on). This will let you continue to write code that reads in a familiar, sequential manner. However, the additional syntax means that the code will execute asynchronously.

Created: 4/11/2011 11:05:28 AM

Last week, three Microsoft Vice Presidents coauthored this post to clarify Microsoft’s position on HTML5 and Silverlight. The answer isn’t too surprising:  both are very important. This is consistent with two requirements we developers have heard since we first started writing software:

  1. This program should run on as many client devices as possible.
  2. This program should provide the best experience possible for the end user on his or her device of choice.

Of course, now, we’re adding a new requirement: users may have more than one device of choice. People carry smart phones, tablets, and laptops for different times in their lives. It’s important to me, as someone that spends much of my professional life using C#, that the choice between the reach of HTML5 and the richness of Silverlight is mine; Microsoft is not making one a better choice than the other. In some product scenarios, I can also choose to invest extra development time and money to support both. Each application is different, and it’s important for us to evaluate each scenario and each application to determine the right choice for our customers.

My own application usage (and yours too) shows what kind of a world we live in: On my phone, I use a facebook app to keep up with friends. At home, I visit the facebook website. I have specific client applications for twitter on my laptop and my phone. We use a chat application (which can be run in a browser) to communicate with co-workers. I’ve got a desktop mail client, a phone mail client, and I occasionally visit the web interface for email. All those experiences are important. The specialized applications provide a simpler and better experience for that single purpose. They also work much, much better on those occasions where I cannot get an internet connection. That’s where Silverlight shines. The websites are available on more different devices. They are easily accessible from a public computer, or a friends computer. That’s where HTML5 shines. Both are important.

Our customers expect us to help them make those same decisions. We need to assess their expected customer base. We need to make serious, thoughtful recommendations about how to provide the best experience for the greatest number of users at the least cost. Those tradeoffs are what engineering is all about. We’ll continue to create applications that use HTML and leverage a browser for the user experience. We’ll continue to create apps using Silverlight. We’ll create apps using Flex or Air for non-windows devices. The decision depends on variables that are specific to the application, and the expected audience.

In the same way, Microsoft is making investments in both HTML5 and Silverlight. They know that some customers will need the reach of HTML5  based applications. Some customers will need the richness of a Silverlight application. Some customers will need both. I expect that we’ll hear more about the HTML5 tools at MIX, because the Silverlight tooling is more mature, and already satisfies many application needs. I’m glad to see the HTML5 investment grow. In today’s world, it’s expensive to create an HTML5 application. The tools are not very mature, and the cost of development is greater than it should be. As the tooling improves, HTML5 will be less expensive. We can recommend a technology stack based on customer needs instead of development costs.

HTML5? Silverlight? Flex? How about all three? In the near future, it will depend on the market for the application, not the cost of development. That’s good news for us as software users and as software developers.

Created: 3/31/2011 12:03:18 PM

These samples use the concepts from the last sample to handle situations where an async operation does not complete as quickly as users might expect.  The first sample shows you how to handle the situation where an async operation should be cancelled because it hasn’t completed in time:

        public async void AsyncTimeoutAfter()
{
try
{
int result = await TimeoutAfter(LongRunningOperation(), 3000);
Console.WriteLine("Operation completed successfully. Result is {0}.",
result);
}
catch (TimeoutException)
{
Console.WriteLine("Timeout - operation took longer than 3 seconds.");
}
}

publicstatic async Task<T> TimeoutAfter<T>(Task<T> task, int delay)
{
await TaskEx.WhenAny(task, TaskEx.Delay(delay));

if (!task.IsCompleted)
thrownew TimeoutException("Timeout hit.");

return await task;
}

public async Task<int> LongRunningOperation()
{
Console.WriteLine("Attempting long-running operation...");

await new SynchronizationContext().SwitchTo();

// Simulate a process that takes between 2 and 4 seconds to complete.
Random r = new Random();
await TaskEx.Delay(r.Next(2000, 4000));

return 123;
}

The interesting new code is in TimeoutAfter(). Notice that it awaits the completion of the long running task, but only up to the delay time of 3 sec. If the operation has not completed, TimeoutAfter throws a TimeoutException.

The other situation is that you may want to restart an async operation that does not complete in time:

        public async void AsyncRetryOnFault()
{
try
{
int result = await RetryOnFault(() => TimeoutAfter(LongRunningOperation(),
3000), 3);
Console.WriteLine("Operation completed successfully. Result is {0}.",
result);
}
catch (TimeoutException)
{
Console.WriteLine("Operation timed out 3 times. Giving up.");
}
}

publicstatic async Task<T> RetryOnFault<T>(Func<Task<T>> function, int maxTries)
{
for (int i = 0; i < maxTries; i++)
{
try { return await function(); }
catch (Exception) { if (i == maxTries - 1) throw; }
}
returndefault(T);
}

public async Task<int> LongRunningOperation()
{
Console.WriteLine("Attempting long-running operation...");

await new SynchronizationContext().SwitchTo();

// Simulate a process that takes between 2 and 4 seconds to complete.
Random r = new Random();
await TaskEx.Delay(r.Next(2000, 4000));

return 123;
}

OK, I’ll admit I’m less than thrilled with using the catch exception / throw logic for flow control. However, it’s a quick sample, so we’ll run with it.  RetryOnFault() starts the async operation. If it does not complete, it increments the number of times it’s been tried. If the operation has been tried enough times, this code assumes it won’t complete. The TimeoutException from the final attempt gets rethrown.

Again, the key is to start the task and await up to a prescribed maximum time. If the task has not completed, take some corrective action. That corrective action may be to restart, or cancel the task.

Created: 3/29/2011 1:00:28 PM

This next set of async samples discusses techniques that enable you to build workflows of the form “do this asynchronously, and then, when this finishes, do that”. The first example shows how to start several tasks in parallel, and continue when all those tasks have finished:

        public async void AsyncWhenAll()
{
Uri[] uris = {
new Uri("http://www.weather.gov"),
new Uri("http://www.weather.gov/climate/"),
new Uri("http://www.weather.gov/rss/") };

string[] pages = await TaskEx.WhenAll(
from uri in uris select new WebClient().DownloadStringTaskAsync(uri));

foreach (string page in pages)
{
WriteLinePageTitle(page);
}
}

The LINQ query starts the three downloads. The await on the same line waits for all three downloads to finish. Then, the titles are printed.

Of course, sometimes, you may want to check against different services for the same answer, and continue execution as soon as you have the first answer.  TaskEx.WhenAny does that for you:

        public async void AsyncWhenAnyRedundancy()
{
string symbol = "ABCXYZ";

var recommendations = new List<Task<bool>>()
{
GetBuyRecommendation1Async(symbol),
GetBuyRecommendation2Async(symbol),
GetBuyRecommendation3Async(symbol)
};
Task<bool> recommendation = await TaskEx.WhenAny(recommendations);
if (await recommendation)
{
Console.WriteLine("Buy stock {0}!", symbol);
}
else
{
Console.WriteLine("Sell stock {0}!", symbol);
}
}


In this sample, the code starts all three requests for a buy/sell recommendations. The first one to finish wins. That answer is printed.

WhenAny has other uses. Suppose you want to start tasks, and when each task finishes you would process the result from that task. Rinse, and repeat for each task. Here’s an example of how you would do that:

        public async void AsyncWhenAnyInterleaving()
{
Uri[] uris = {
new Uri("http://www.weather.gov"),
new Uri("http://www.weather.gov/climate/"),
new Uri("http://www.weather.gov/rss/") };


List<Task<string>> downloadTasks = (
from uri in uris select new WebClient().DownloadStringTaskAsync(uri)).
ToList();

while (downloadTasks.Count > 0)
{
Task<string> downloadTask = await TaskEx.WhenAny(downloadTasks);
downloadTasks.Remove(downloadTask);

string page = await downloadTask;
WriteLinePageTitle(page);
}
}

The new code in his example is in the while loop. It awaits a result from any of the currently executing tasks.  When a result is available, it removes that task from the list of current tasks, and processes its result.

This process of awaiting and processing one result continues until all tasks have been processed.

You can also use WhenAny to limit the number of current tasks running. This sample adds new tasks when the current list of running tasks has fewer elements than some known limit. Tasks are added until the limit is reached. Then, the list of tasks is awaited. When a result is available, it gets processed, and then if the list of running tasks is below the threshold, and there is more work to do, another task is started and added to the list:

        public async void AsyncWhenAnyThrottling()
{
constint CONCURRENCY_LEVEL = 4; // Maximum of 4 requests at a time

Uri[] uris = {
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h000.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h001.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h002.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h003.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h010.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h011.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h012.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h013.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h020.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h021.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h022.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h023.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h030.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h031.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h032.jpeg?g=400"),
new Uri("http://ecn.t0.tiles.virtualearth.net/tiles/h033.jpeg?g=400"),
};
int nextIndex = 0;
var downloadTasks = new List<Task<string>>();
while (nextIndex < CONCURRENCY_LEVEL && nextIndex < uris.Length)
{
Console.WriteLine("Queuing up initial download #{0}.", nextIndex + 1);
downloadTasks.Add(
new WebClient().DownloadStringTaskAsync(uris[nextIndex]));
nextIndex++;
}

while (downloadTasks.Count > 0)
{
try
{
Task<string> downloadTask = await TaskEx.WhenAny(downloadTasks);
downloadTasks.Remove(downloadTask);

string str = await downloadTask;
int length = str.Length;

Console.WriteLine("* Downloaded {0}-byte image.", length);
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }

if (nextIndex < uris.Length)
{
Console.WriteLine("New download slot available. Queuing up download #{0}.",
nextIndex + 1);
downloadTasks.Add(new WebClient().DownloadStringTaskAsync(uris[nextIndex]));
nextIndex++;
}
}

}

Once again, the while loop toward the end is the interesting code. Await a result. Process the result. Then, if there is more work, start the next task.
 
Finally, there is a delay API should you need to wait for a prescribed amount of time, while keeping the UI responsive:
 
        public async void AsyncDelay()
{
Console.WriteLine("Before the delay.");
await TaskEx.Delay(3000);
Console.WriteLine("After the delay.");
}

Created: 3/4/2011 4:40:49 PM

I recorded a DNRTV with Carl Franklin a little while ago, and one of the viewers, Kyle Szklenski posted this comment:

I listened to the DNR TV today with Bill Wagner on dynamic typing. I was really, really, ecstatically happy to hear fellow champions of static typing. It's all too often that my coworkers or other people online tout the benefits of making everything in your application dynamic, and it makes me physically ill to have to listen to it. Hyperbole aside, I think that if you cannot design a system to work with static typing, then there's probably something wrong with your design sense. Thanks for the awesome presentation, and am looking forward to hearing Bill discuss the new async stuff!

I’m not sure I’d phrase it that strongly. It’s true that C# is a static language. Every feature in the language emphasizes a belief in the benefits static typing. It is true that you could design any system in a static language, but that doesn’t mean it’s the best way to design any system. The features added in C# 4.0 demonstrate that.  There are idioms where having dynamic typing is a great benefit. COM interop, runtime type checking, and language interop are obvious examples. Without adding language features, these idioms require pages of code.

That’s work to write the code.
That’s work to test the code.
That’s work to maintain the code.
That’s pages work to debug and extend the code.

Language features that shrink those pages to a few lines (with the same features) should be applauded.  We get done faster, with fewer bugs, and have more readable code.

However, adding dynamic types to your program has a cost. It is a very different style, and the rough edges where dynamic and static types meet can produce surprising behavior for those expecting the familiar. That causes disruption to our thinking when we try to understand programs. It can increase bugs.

For this reason, and many others, I tell customers to view dynamic is a very powerful feature, but one that must be kept in a pen. Use dynamic typing where it helps. Don’t make everything dynamic, and prefer narrow scopes for variables that are statically typed to be dynamic.

Created: 2/15/2011 8:37:01 PM

The Pex team has created a site that provides a great tool to exercise your brain, learn a bit of code, and see a bit about Pex.

To use it, just go to the PexForFun site. There are puzzles, learning exercises, and duels.  Register and you can create your own challenges. (I’ll be doing this over the next month or so.)

The puzzle structure is a great demonstration of Pex. When you start a new puzzle, you have a empty implementation. You can click Ask Pex to get some test results on the hidden successful implementation. Pex then executes those tests on your code. You’ll see some failures, and you can fix your code to make the tests pass.

Then, you can click “Ask Pex” again, and see if a more extensive test suite still passes. Iterating this way gets you to write more code and your implementation gets closer to the expected solution. If you are not familiar with Test Driven Development, I highly recommend it. You’ll get a real feel for creating code to an executable specification instead of a written spec.

All in all, there are several reasons I like playing with PexForFun:

  1. It’s practice for Test Driven Development. you start with an empty implementation, and see a few failing tests. Keep making a few pass and you’ll get more tests. After a few iterations you’ll have everything working.
  2. It will give you some practice writing tests. Pex generates tests by analyzing your code. It determines a number of interesting inputs to code by analyzing its structure. You can read an overview here: http://www.pexforfun.com/Documentation.aspx#HowDoesPexWork By seeing the inputs it chooses, you’ll get some ideas how to write your own tests. By thinking about inputs it chooses to ignore, you can get better at writing useful tests instead of more tests.
  3. It exercises your brain. The puzzles range from introductory to rather complicated.
  4. You can pick different languages for your puzzles: C#, VB and F#.

Learn some new techniques, exercise your brain, and most of all: Have fun!

Created: 2/10/2011 2:54:55 PM

This is one of those small tips that took me way too long to find, and I figure if I needed to search that long to find the right answer, I might be able to help others by posting it here.

One practice I usually use for WPF and Silverlight applications is to create a 1:1 correspondence between my Views (Windows, User Controls, and so one) and my ViewModel classes. I find that practice makes it easier to ensure that I’ve tested the behavior of the different visual elements in the program.

In general, that works great. Each view has its own DataContext, and that DataContext points to a ViewModel that holds the properties for that view. But, there’s one place where that falls down: having a parent view control the visibility of the child control.

As an example, one windows has two child controls that occupy the same location. The associated view model assures that exactly of the two child controls is visible at one time:

          <
          c:FirstControl
        
          Grid.ColumnSpan="3"
          Visibility
          ="{Binding FirstControlVisible}"
          />
        
          <
          c:SecondControl
        
          Grid.ColumnSpan="3"
          Visibility
          ="{Binding SecondControlVisible}"
          />
        

So far, so good.  This ran great in prototypes, but once I created the specific ViewModel classes for FirstControl and SecondControl, it stopped working. No matter what I did, both controls were visible. I ran it through the debugger, and I was getting errors saying that the DataContext did not have the correct property.

Hmm. I knew my ViewModel had the right property (it worked before, all tests were still green), so what was going on? Well, the problem was that the binding was using the DataContext for each user control, not for the parent window.

I now had a different ViewModel for each View. That means each view has a different object for its DataContext. In order to get the parent DataContext, you have to specify the source in the binding.  It looks like the following:

          <
          c:FirstControl
        
          Grid.ColumnSpan="3"
          Visibility
          ="{Binding Path=DataContext.FirstControlVisible,    RelativeSource={RelativeSource AncestorType=Window}}"
          />
        
          <
          c:SecondControl
        
          Grid.ColumnSpan="3"
          Visibility
          ="{Binding Path=DataContext.SecondControlVisible,RelativeSource={RelativeSource AncestorType=Window}}"
          />
        

Note the extra information on the binding to specify the parent.

You may be thinking why you don’t need this more often. My UI was working in early prototypes before I flushed out more functionality. WPF has some binding features that helps you out. If a View’s DataContext is null, the binding infrastructure will use the parent DataContext. Before I built the child ViewModels, everything worked.

I don’t recommend binding to properties in another DataContext as a regular practice, but for the visibility of child controls, it does feel very natural. Just rememeber to set the DataContext to the right relative source.

Created: 2/8/2011 4:14:55 PM

The most often question I get these days is “Should I invest in Windows Phone 7?” It’s a difficult question. The people asking me are making large bets on their future investment in technology. I don’t want out customers to leap into an area with no future, nor do I want them to miss what could be a major growth opportunity.

In the mobile market, success is not a simple yes or no question. The continued growth of the mobile market and the apps market are critical to the Windows Phone 7 success story.

For Windows Phone 7 to succeed, iPhone and Android do not have to fail. This is a point that often needs to be restated to businesspeople. The mobile phone market grew 17.9% in Q4 2010 according to research firm IDC (http://www.mobiletor.com/2011/02/03/idc-traces-17-9-growth-in-global-mobile-phone-market-for-q410/).With that kind of growth, Windows Phone 7 can achieve success without taking sales from other platforms.

Unlike a mature and stable market (like autos), one company’s gains do not necessarily imply another company’s losses. From that perspective, I don’t expect Windows Phone 7 to take conquest sales from iPhone or Android, at least not until users of those devices reach the natural upgrade cycle for their devices (roughly 2 years out). For some, especially those experienced in mature markets, that means Windows Phone 7 won’t succeed.

But that isn’t necessarily the correct perspective. Microsoft surely has sales goals for the platform. That’s their metric for success, which probably involves taking some market share from iPhone and Android. For the rest of us business owners, the question is whether or not to invest in applications for the Windows Phone 7 platform.

The apps story is critical because it drives device usage and customer loyalty. The “killer apps”—like Mobiata’s FlightTracker—drive mobile phone purchasing decisions Microsoft needs to have compelling reasons for developers to create applications for WP7, and more importantly, businesses need to have a market for those applications.

The presence of applications will feed market share, and vice versa. Windows Phone 7 will be a success if it attains enough market share by 2012 that mobile developers believe that it is a necessary target platform, along with iPhone and Android. Windows Phone 7 succeeds and gains momentum if it becomes one of the platforms that are mandatory for successful applications. However, if developers believe they can ignore the platform through the end of this year, it won’t succeed.

It’s that perspective that businesspeople need to understand. It won’t matter which platform has the most market share in your business (or personal) buying decisions. What will matter is which platforms are on the ‘must support’ list. That’s the metric of success that will drive your business. You can’t afford to ignore any of the top platforms.

So, where’s the recommendation?

Right now, Windows Phone 7 has a very small market share (relatively speaking). That share will go up, and the real numbers of devices will go up. I don’t know how much, and neither do you. What I recommend is for our customers to architect mobile applications carefully, so that the largest amount of code runs in the cloud and can be accessed from any device. Then, the incremental cost of supporting new devices is smallest. That enables our customers to watch, and still respond quickly to the actual market data, rather than making a decision prematurely.

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.