Bill Blogs in C# -- async

Bill Blogs in C# -- async

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: 10/20/2011 6:31:39 PM

First, let me preface this by saying I’m truly amazed at the quality and quantity of of submissions.  I’m not on the speaker selection committee, so I don’t see all the abstracts. Several colleagues whom I greatly respect have shared their talk ideas.  There were simply more great talks than they were slots.  I can’t imagine a harder task than being part of the CodeMash speaker selection committee It’s especially hard because there are so many different technologies represented.

That said, I’m super thrilled to have made the list for 2012.  I’ve actually got two talks, and I’m excited to deliver both of them.

The first is C# Stunt Coding: I dare you to try this at home. In this talk, I get to stretch the C# language in ways you don’t expect.  I’ll show techniques to do things you don’t think C# can do. Every technique will come with the warning that it’s one of those techniques that you should only apply in rare situations.  Knowing most C# developers and CodeMash attendees, that will only make you want to use them more.

The second is Async from the Outside. This talk will discuss how the async and await keywords will change the way you code in C#. I’ll discuss the async features, and go over coding practices you should adopt to make sure that you’re making the most use of these new tools.  You may have heard that async APIs are much more prominent in the WinRT library. That’s true, and that’s why many of the demos here will be designed for the Windows 8 Metro platform. People interested in the inner workings of the async details should attend Async from the Inside given by Jon Skeet.

Created: 9/19/2011 5:27:05 PM

I had to fly out early on Friday, so the only session I attended on Friday was Mads Torgersen and Alex Turner’s talk on the async features in C# 5.0. I’ll start with the punchline:

In C# and async, you’ll never write another callback.

In a nutshell, that’s what these features add to the language: Transformations so that you can write code that looks and reads like today’s synchronous code, and the compiler will transform that into the necessary constructs for async behavior. The compiler will create the state machine, and write the callback code for you.

The second key point is that all the languages (C++/C#/VB.NET/F#/Javascript) all support this construct. It’s also baked into the WinRT libraries. You can await WinRT async operations, just like you can await C# async methods.

There is, however, one very important distinction:

C# / .NET tasks are created “hot”, meaning they start immediately. WinRT async methods are created “cold”, meaning they don’t start until you await them.

The .NET languages are leveraging Task<T> and extension methods which take or return Task<T> to make the operation of WinRT async methods behave as similar as possible to C# async methods. For example, you can use the Start() and StartAsTask() extension methods to start a WinRT async operation. StartAsTask() also massages the WinRT awaitable to a C# Task<T> so that it supports cancellation.

Task<T> is also used to provide some other useful async constructs. Task.Run() enables you to write a compute intensive task for a background thread, and leverage the await pattern. The library handles the thread marshaling so that the continuation executes on the foreground thread when the background thread finishes its work.

Task<T> also contains the Task.Delay() method that you can use to easily check for timeouts expiring in long running operations.

Admittedly, this is a short post. Watch their talk, and try it out yourself.

You’ll never write another callback.

Created: 7/6/2011 1:44:55 PM

While on vacation last week, I read Jon Skeet’s Eduasync series. (Yeah I know, but I also had a lot of fun outdoors). It is a great description of how the async features work in the CTP (and how these features are specified to work in the upcoming version of C#). Jon’s posts explain how async features compile down to constructs you could write today. In some cases, you may need to go down to the level of IL to create the constructs the compiler generates on your behalf, but understanding Jon’s posts will provide you with a strong understanding of what the compiler does on your behalf.

That’s one way to learn: understand how a new language construct maps to existing constructs in your mind. Once that happens, you have a mental model from which to work, and you can use the new features. For a while, you’ll mentally translate the new syntax to the existing construct in your own mind, but eventually, the new constructs become more natural.

I prefer to explain these new features from a different perspective. Unless you are implementing a compiler, I think it is better to understand language features at a more abstract level. Rather than understand how new features are implemented, and how they map to existing constructs, try to understand what it does, and semantically what the new features enable. This give you a different mental model. It no longer matters how new features map to existing constructs. What matters is what new constructs mean.

In LINQ, for instance, I think it’s better to understand that the parameters to many of the methods in System.Linq.Enumerable is code. You’re treating code as data. I think that’s a more important concept than knowing that the compiler writes methods, creates delegates, and may create classes to implement closures. You’re treating code as data. That’s (to me) the important lesson to learn.

Different people learn differently. You should read from different perspectives, and figure out which perspective works best for you. In the meantime, read multiple sources and multiple perspectives.  I write from the perspective that I think enables the most learning. Jon writes from a different perspective. Sometimes I prefer mine; sometimes I prefer his. Most of all, I think seeing things from different perspectives helps the most.

Created: 5/18/2011 3:48:50 PM

Authors note:  Lucian contacted me after my last post on the authorship of the async samples he’s hosting here. While he’s hosting them, he did not write them (mostly).  Most of the credit goes to Alex Turner, on the C# compiler team.

I’ll cover the last sets of samples in this one post. Then, I can get on with writing my own async samples. This set shows some of the additions to existing APIs that enables integration with the new language features.

You’ve already seen WebRequest.GetResponseAsync(). The new addition discussed in this post is in System.IO.Stream.  This class already had a Stream.CopyTo() method. The next version will add a Stream.CopyToAsync().

        public async void AsyncStreamCopyTo()
{
MemoryStream destination = new MemoryStream();

// Download a file.
var request = WebRequest.CreateHttp("http://www.weather.gov/climate/");
using (var response = await request.GetResponseAsync())
{
using (var source = response.GetResponseStream())
{
Console.WriteLine("Source length: {0}", response.ContentLength);

// Copy source to destination.
await source.CopyToAsync(destination);
}
}

Console.WriteLine("Destination length: {0}", destination.Length.ToString());

// NOTE: If Just My Code is on, VS will currently show a first-chance exception here.
// You may hit F5 to continue running after seeing the exception.
}
Notice that this code now calls CopyToAsync() instead of CopyTo(), and the code awaits that response. Once this code gets the response it begins copying the response. That copy also happens asynchronously.
 
Next, there is a set of samples that shows the updates to the System.Net APIs.  There is now a DownloadStringTaskAsync() as well as a DownloadString() API on the WebClient class:
 
        public async void AsyncWebRequestDownloadStringAsyncCustomized()
{
WebClient client = new WebClient();

client.BaseAddress = "http://www.weather.gov";

Console.WriteLine("Base address set.");

WriteLinePageTitle(await
client.DownloadStringTaskAsync(new Uri("/", UriKind.Relative)));
WriteLinePageTitle(await
client.DownloadStringTaskAsync(new Uri("/climate/", UriKind.Relative)));
WriteLinePageTitle(await
client.DownloadStringTaskAsync(new Uri("/rss/", UriKind.Relative)));
}

Finally, the WebRequest class contains a GetRequestAsync API as well as a GetRequest API.

        public async void AsyncWebRequestGetResponse()
{
var response = await WebRequest.Create(
"http://www.weather.gov").GetResponseAsync();
var stream = response.GetResponseStream();
Console.WriteLine("First byte: {0}",
stream.ReadByte().ToString("X2"));
}

What we learned from these samples is that the BCL will be updated with new methods that will make it easier to use the async language features with the rich APIs we already have in the .NET framework.
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: 5/6/2011 2:05:50 PM

Update:  Thanks to Jon Skeet, the description of what can be awaited is more accurate.

After a brief spring hiatus, it’s time to continue examining the Async samples provided by Lucian Wishik.

The next set of samples shows how the await keyword integrates with other language features and expression types. This set, which has several samples, shows how well the new language features integrate with existing language features.

The key takeaway:  The await keyword can await any expression that has an appropriate GetAwaiter() method. This includes any expression that returns a Task, or a Task<T>.

Corollary: Any expression that returns Task or Task<T> may be awaited.

For example, the first sample in this set shows that you may await a member access expression:

        public async void AsyncMemberAccessWithin()
{
var pair = new StringTaskPair();
pair.Task1 = new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov"));
pair.Task2 = new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/climate/"));

WriteLinePageTitle(await pair.Task2);
}

publicclass StringTaskPair
{
public Task<string> Task1 { get; set; }
public Task<string> Task2 { get; set; }
}

Note that StringTaskPair.Task1 and StringTaskPair.Task2 are both typed as Task<string>. You can set them to expressions that return Task<string>. Because they are Task<string>, you can await the results of those actions.

The remaining samples show many different expressions in the C# language. You can await any of those expressions.  There are a few that are non-obvious that deserve special mention.

You can await the result of invoking a delegate:

        public async void AsyncInvocationWithin()
{
var topic = "monkeys";

Func<string, Task<string>> searchTaskGenerator =
s => new WebClient().DownloadStringTaskAsync(
new Uri(string.Format(
"http://odata.netflix.com/Catalog/Titles/$count?$filter=substringof('{0}',Name)", s)));

Console.WriteLine("{0} movies about {1}.", await searchTaskGenerator(topic), topic);
}

You can use conversion operators to coerce a result to a Task<T> that can be awaited:

        public async void AsyncExplicitConversionWithin()
{
var sr = new StringCalculation();

Console.WriteLine(await (Task<string>)sr);
}

publicclass StringCalculation
{
publicstaticexplicitoperator Task<string>(StringCalculation sr)
{
return TaskEx.Run(() =>
{
Thread.Sleep(1000); // Simulate calculation to produce a string.
return"FooBar";
});
}
}

The sample above demonstrates that you can create overloaded operators that leverage the async pattern. You can see the overloaded explicit conversion operator. In fact, you can create overloaded operators that change the standard signature such that the result of the operator is async.

For example, many of the samples in this section leverage relational operators that leverage the async pattern. This samples shows how you can define an async operator == that will tell you *some time in the future* whether or not two remote integers are the same:

        public async void AsyncEqualsWithin()
{
RemoteInteger remoteInt1 = await RemoteInteger.CreateAsync(200);
RemoteInteger remoteInt2 = await RemoteInteger.CreateAsync(34);

Console.WriteLine(await (remoteInt1 == remoteInt2));
}

publicclass RemoteInteger
{
privateintvalue; // Hold the value that we're simulating remote storage of.

publicstatic Task<RemoteInteger> CreateAsync(int i)
{
// Simulate sending i to a remote server:
var creation = new Task<RemoteInteger>(() => new RemoteInteger(i));
creation.Start();
return creation;
}
private RemoteInteger(int i) { value = i; }

publicstatic Task<bool> operator ==(RemoteInteger i1, RemoteInteger i2)
{
// Simulate remote equality comparison of i1 and i2:
var equality = new Task<bool>(() => (i1.value == i2.value));
equality.Start();
return equality;
}
publicoverridebool Equals(object obj) { thrownew NotSupportedException(); }
publicoverrideint GetHashCode() { thrownew NotSupportedException(); }
}

It’s important to note that this version of operator==() returns Task<bool> instead of bool.  By doing so, it can be awaited, as you see in the AsyncEqualsWithin() method.

Disclaimer: This is really new syntax, and I’ve had minimal experience with it.

OK, now that the disclaimer is out of the way, here’s my opinion: I like the fact that the languages team (C# and VB.NET) enables async semantics on all these expression types. However, this should be used with caution. Developers will have the natural expectation that these operators are synchronous and complete quickly. This is no different than the expectation that property accessors are quick operations. Even though it is syntactically correct, async overloaded operators will have characteristics that developers find surprising. My initial reaction is that this is not a good way to leverage these features.

Overall, it’s fantastic to see how well integrated the async keyword is with the rest of the C# language. It makes it easier to exted designs to include async capabilities with minimal extra ceremony. As we all gain more experience using these features, we’ll develop guidance for creating idioms that work well and set correct expectations for other developers.

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/13/2011 5:42:59 PM

It’s time for another look at the upcoming async features in C#. This time it’s different ways to control switching threads.

My preferred way to switch threads is to use the TaskEx.Run() method. You write a lambda expression for the work to be done on a background thread. That syntax nicely scopes the context for the work on the background:

        public async void AsyncRunCPU()
{
Console.WriteLine("On the UI thread.");

int result = await TaskEx.Run(() =>
{
Console.WriteLine
("Starting CPU-intensive work on background thread...");
int work = DoCpuIntensiveWork();
Console.WriteLine("Done with CPU-intensive work!");
return work;
});

Console.WriteLine("Back on the UI thread. Result is {0}.",
result);
}
The new async code provides another way to switch threads: SynchronizationContext.SwitchTo(), and Dispatcher.SwitchTo(). Using these methods, you switch to a background thread or to the foreground thread, respectively.
The advantage is that the code reads a bit more naturally. You can read the algorithm linearly, including the portions that run on the background thread.
 
        public async void AsyncSwitchToCPU()
{
Console.WriteLine("On the UI thread.");

// Switch to a thread pool thread
await new SynchronizationContext().SwitchTo();

Console.WriteLine("Starting CPU-intensive work on background thread...");
int result = DoCpuIntensiveWork();
Console.WriteLine("Done with CPU-intensive work!");

// Switch back to UI thread
await Dispatcher.SwitchTo();

Console.WriteLine("Back on the UI thread. Result is {0}.", result);
}

In this example, its clear and easy to read when the thread contexts change. However, those calls to SynchronizationContext().SwitchTo() and Dispatcher.SwitchTo() might be in different methods. I think that would get confusing in a large codebase.

One other use of SynchronizationContext.SwitchTo() is that you can use it to switch the context to a background thread before starting several background operations. Doing so avoids many more context switches, as each async operation finishes:
 
        public async void AsyncSwitchToThreadPool()
{
Uri[] uris = {
new Uri("http://www.weather.gov"),
new Uri("http://www.weather.gov/climate/"),
new Uri("http://www.weather.gov/rss/") };

// Avoid hops after each async completion
await new SynchronizationContext().SwitchTo();

int totalLength = 0;
foreach (var uri in uris)
{
string s = await new WebClient().DownloadStringTaskAsync(uri);
totalLength += s.Length;
}

// Switch back to UI thread
await Dispatcher.SwitchTo();

Console.WriteLine("Back on the UI thread. Total length of pages is {0}.",
totalLength);
}

The above sample switches execution to a background thread before starting the first network request. That means all three network requests are on background threads, and this code avoids the context switch back to the foreground as each request finishes.
Created: 4/4/2011 12:02:13 PM

The ninth set of samples discusses migrating existing asynchronous programming models to the upcoming async syntax.  The first sample shows how you can wrap code that uses the existing Asynchronous Programming Model library to use the new async features.

        public async void AsyncFromAPM()
{
var response = await WebRequest.Create("http://www.weather.gov").
GetResponseAsync();
var stream = response.GetResponseStream();
var buffer = newbyte[1024];
int count;
while ((count = await ReadAsync(stream, buffer, 0, 1024)) > 0)
{
Console.Write(Encoding.UTF8.GetString(buffer, 0, count));
}
}

publicstatic Task<int> ReadAsync(Stream stream, byte[] buffer,
int offset, int count)
{
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(buffer, offset, count, iar =>
{
try { tcs.TrySetResult(stream.EndRead(iar)); }
catch (Exception exc) { tcs.TrySetException(exc); }
}, null);
return tcs.Task;
}
The interesting code here is in the ReadAsync method. It creates a TaskCompletionSource that carries the result. The ReadAsync method returns the task, which can be awaited by the caller. Once the read has completed, the calling method continues execution.
 
If you’ve used the current Asynchronous Programming Model, you should appreciate how much more readable and concise this version is.
 
The next sample shows how you would convert a more extensive asynchronous operation to use the proposed syntax. This version leverages the new async features in the language in a method that supports cancellation, and reports progress:
 
        private CancellationTokenSource cts;

public async Task AsyncFromEAP()
{
cts = new CancellationTokenSource();
var progress = new EventProgress<DownloadProgressChangedEventArgs>();
progress.ProgressChanged += (sender, e) =>
{ ProgressBar.Value = e.Value.ProgressPercentage; };

try
{
WriteLinePageTitle(await DownloadStringAsync(new Uri("http://www.weather.gov"),
cts.Token, progress));
}
catch
{
Console.WriteLine("Downloading canceled.");
}
}

publicstatic Task<string> DownloadStringAsync(Uri address,
CancellationToken cancel, IProgress<DownloadProgressChangedEventArgs> progress)
{
// Create the task to be returned
var tcs = new TaskCompletionSource<string>(address);
var webClient = new WebClient();

// Register the cancellation token
var ctr = cancel.Register(webClient.CancelAsync);

// Setup the callback event handlers
webClient.DownloadProgressChanged += (s, e) => progress.Report(e);
webClient.DownloadStringCompleted += (s, e) =>
{
ctr.Dispose();
if (e.Error != null) tcs.TrySetException(e.Error);
elseif (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};

// Start the async operation.
webClient.DownloadStringAsync(address, tcs);

// Return the task that represents the async operation
return tcs.Task;
}

The heavy lifting here is done by the DownloadStringAsync method. It puts initializes the cancellation callback, the progress reporting callback, and the completion callback. The last thing is does is to start the download, and return the task that can be awaited.
 
More importantly, look at the calling code, the AsyncFromEAP() method. The new syntax and language features makes this method much more readable than the equivalent code would be using previous features.
 
The final sample in this section shows how you can convert an existing synchronous method to an asynchronous method:
 
ublic staticvoid CopyTo(Stream source, Stream destination)
{
// Old synchronous implementation:

var buffer = newbyte[0x1000];
int bytesRead;
long totalRead = 0;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
destination.Write(buffer, 0, bytesRead);
totalRead += bytesRead;
}
}

publicstatic async Task CopyToAsync(Stream source, Stream destination,
CancellationToken cancellationToken,
IProgress<long> progress)
{
// New asynchronous implementation:

var buffer = newbyte[0x1000];
int bytesRead;
long totalRead = 0;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await destination.WriteAsync(buffer, 0, bytesRead);
cancellationToken.ThrowIfCancellationRequested(); // cancellation support
totalRead += bytesRead;
progress.Report(totalRead); // progress support
}
}

The final sample in this set shows how easy it is to convert an existing synchronous method to async you use the new syntax. It’s as simple as calling ReadAsync instead of Read, and WriteAsync instead of Write. For bonus points, this conversion includes an IProgress delegate so that it can report progress.
 
The new version is no more complicated. The code isn’t longer. That’s one of the reasons I really like the direction that C# async support is taking.
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/25/2011 12:07:05 PM

So far, we’ve only discussed calling async methods. The next set of samples discusses how to declare async methods.

I’m going to discuss these three samples in a different order than they appear on Lucian’s site. I think a different order will make it easier to understand the concepts. Let’s start with an async method that has a void return:

        public
        void AsyncReturnVoid()
{
Console.WriteLine("*** BEFORE CALL ***");
VoidReturningMethod();
Console.WriteLine("*** AFTER CALL ***");
}

private async void VoidReturningMethod()
{
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov")));
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/climate/")));
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/rss/")));
}

The output from this sample appears below:

*** BEFORE CALL ***
*** AFTER CALL ***
Page title: NOAA's National Weather Service
Page title: NOAA's National Weather Service - National Climate
Page title: RSS Libraries and Podcast - NOAA's National Weather Service

This is a “fire and forget” scenario. VoidReturningMethod returns to the caller as soon as it encounters its first await. However, the VoidReturningMethod is still executing asynchronously. That’s why you see the output in the order you see above.

Next, let’s examine how to declare an async method that returns a Task<T>. The next sample shows that scenario:

        public async void AsyncReturnTaskOfT()
{
Console.WriteLine("*** BEFORE CALL ***");
Console.WriteLine(await TaskOfStringReturningMethod());
Console.WriteLine("*** AFTER CALL ***");
}

private async Task<string> TaskOfStringReturningMethod()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(GetPageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov"))));
sb.AppendLine(GetPageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/climate/"))));
sb.AppendLine(GetPageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/rss/"))));
return sb.ToString();
}

This code does await all the async operations. The output is in the order you’d expect: all the page titles are printed between the “Before Call” and the “After Call” lines. The AsyncReturnTaskOfT() method awaits the result of the TaskOfStringReturningMethod().

Finally, let’s examine the sample that returns a Task:

        public async void AsyncReturnTask()
{
Console.WriteLine("*** BEFORE CALL ***");
await TaskReturningMethod();
Console.WriteLine("*** AFTER CALL ***");
}

private async Task TaskReturningMethod()
{
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov")));
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/climate/")));
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/rss/")));
}

This one works similar to the second sample above. The TaskReturningMethod returns a Task as soon as it encounters it’s first await (when it downloads the page at www.weather.gov). And yet, when you look at the output, you’ll see this:

*** BEFORE CALL ***
Page title: NOAA's National Weather Service
Page title: NOAA's National Weather Service - National Climate
Page title: RSS Libraries and Podcast - NOAA's National Weather Service
*** AFTER CALL ***

This one gets a bit complicated. Here’s what happens:

  1. The TaskReturningMethod executes until the first await.
  2. Control returns to AsynReturningMethod, which is awaiting that Task.
  3. The first download finishes, and that first Task executes its Continuation: printing the first title, starting the next download. There’s another await there.
  4. Control returns to TaskReturningMethod, which is still awaiting. Once the second page finishes downloading, its continuation executes: printing the second title, and starting the final download. Control returns to the (still) awaiting AsyncReturningMethod.
  5. That final download finishes, and now its continuation executes: printing the final page title.
  6. Having finished all the async tasks, control returns for the last time to AsyncReturningMethod. The async tasks have all completed, so that method is done Awaiting. Now “After Call” gets printed.

The mechanics are rather complicated, but conceptually the behavior is what you want: The three downloads all happen asynchronously. Anytime code awaits that action, that control flow stops until the awaited action completes. In the end, the code executes, more or less, in the same order as an imperative version of the same code, but many parts of it can execute asynchronously.

Thanks to Chris Marinos and Jay Wren who helped me work through the flow of this sample.

Created: 3/23/2011 12:08:49 PM

To some degree, the async samples present an overly simplified view of exception handling in async methods. Despite that, it is a good overview of how the team wanted to make the async methods behave as much like serial methods as possible. First, exceptions will propagate from async methods to the code that awaits the async result:

        public async void AsyncTryCatch()
{
try
{
WriteLinePageTitle(await new WebClient().DownloadStringTaskAsync(
new Uri("http://www.weather.gov/clmitae/")));
}
catch
{
Console.WriteLine("Error loading page.");
}
}

Exceptions will propagate out to the caller that is awaiting the completion of an async call. In the example above, DownloadStringTaskAsync() throws an exception, and the awaiting code catches is.

The same rules apply for finally blocks:

        public async void AsyncTryFinally()
{
Console.WriteLine("Download process beginning...");
try
{
WriteLinePageTitle(await DownloadStringTaskSlowNetworkAsync(
new Uri("http://www.weather.gov"), cts.Token));
WriteLinePageTitle(await DownloadStringTaskSlowNetworkAsync(
new Uri("http://www.weather.gov/clmitae/"), cts.Token));
WriteLinePageTitle(await DownloadStringTaskSlowNetworkAsync(
new Uri("http://www.weather.gov/rss/"), cts.Token));
}
catch
{
Console.WriteLine("There was an error downloading the pages.");
}
finally
{
Console.WriteLine("Download process completed.");
}
Console.WriteLine("Success!");
}
 
These two samples work because exceptions thrown from inside a Task-returning method can be caught by the code awaiting that task:
 
        public async void AsyncThrow()
{
var uris = new List<Uri> {
new Uri("http://www.weather.gov/climate/"),
new Uri("http://www.weather.gov"),
new Uri("http://www.weather.gov/rss/") };

try
{
await CheckPageSizes(uris);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

public async Task CheckPageSizes(IList<Uri> uris)
{
foreach (var uri in uris)
{
string page = await new WebClient().DownloadStringTaskAsync(uri);

if (page.Length < 50000)
thrownew Exception(String.Format("{0} is too small!", uri));

Console.WriteLine("{0} contains {1} bytes.", uri, page.Length);
}
}

What’s not covered here is any of the more complicated flows that you’ll need to determine which of the async tasks caused the error or how many of the tasks did cause an error. That’s handled by AggregateExceptions, and is the subject for another day.

Created: 3/15/2011 11:43:51 AM

The next async samples explore how to report progress while async operations execute.

There’s only one sample here, but it’s somewhat more involved.  The client method (calling async methods) method follows:

        public async Task AsyncProgressPolling()
{
cts = new CancellationTokenSource();
var progress = new EventProgress<GetAllPingsPartialResult>();

try
{
progress.ProgressChanged += (source, e) =>
{
ProgressBar.Value = e.Value.Count % 100;
};
foreach (var item in await GetAllPingsAsync(cts.Token, progress))
{
Console.WriteLine(item);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation canceled.");
}
}
 
The new code creates an EventProgress<T> object. This object supports a ProgressChanged event that enables the worker tasks to report progress as their tasks progress. When the event is raised, the progress bar moves ahead.
 
The other side of this convention is to write the code that runs the background operation in such a way that it raises those events as it progresses. Here’s the code that runs the background tasks, and raises that progress event:
 
        public async Task<string[]> GetAllPingsAsync(
CancellationToken cancel, IProgress<GetAllPingsPartialResult> progress)
{
var sites = new List<string>();
for (int i = 0; i < 30; i++)
{
sites.Add("http://www.microsoft.com");
sites.Add("http://msdn.microsoft.com");
sites.Add("http://www.xbox.com");
}
var results = new List<string>(sites.Count);
foreach (var site in sites)
{
cancel.ThrowIfCancellationRequested();
var time = DateTime.UtcNow;
try {await new WebClient().DownloadStringTaskAsync(site);}
catch {}
var ms = (DateTime.UtcNow - time).TotalMilliseconds;
results.Add(String.Format("[{0}] {1}", ms, site));
if (progress != null)
progress.Report(new GetAllPingsPartialResult()
{
Pings = new ReadOnlyCollection<string>(results),
Count = results.Count
});
}
return results.ToArray();
}

This method contains the familiar event source pattern.
As this method does its work, it raises the Progress event by calling progress.Report(), passing it the current results, and the count of the results.
 

Key Points

Methods designed to be run asynchronously should consider supporting progress reporting. There’s a standard way to do it, and you only report progress to those callers that ask for it.
Client code can ask for progress using the same mechanism.

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.