Skip to content

Instantly share code, notes, and snippets.

@aliostad
Created June 9, 2012 16:47
Show Gist options
  • Save aliostad/2901745 to your computer and use it in GitHub Desktop.
Save aliostad/2901745 to your computer and use it in GitHub Desktop.
ASYNC/AWAIT - To repro problems Tugberk experienced. VS2012 - .NET 4.5
OK I have written this sample in VS 2012.
Here is output from trace:
Label: Before await |<Get>d__0.MoveNext() - Thread name: ''
Label: Inside async |ValuesController.<DoWaitAsync>b__3() - Thread name: ''
Label: Inside async after sleep |ValuesController.<DoWaitAsync>b__3() - Thread name: 'ValuesController.<DoWaitAsync>b__3()_ce0a3be5377f41fe8056b5fac2fd9464'
Label: After await |<Get>d__0.MoveNext() - Thread name: ''
Label: Beginning dowork |ValuesController.doWork() - Thread name: '<Get>d__0.MoveNext()_fc4664d4088d450e8140ad5b943ef1d3'
iisexpress.exe Information: 0 : doWork is running...System.Web.HttpContext
Label: Ending dowork |ValuesController.doWork() - Thread name: '<Get>d__0.MoveNext()_fc4664d4088d450e8140ad5b943ef1d3'
Label: After dowork |<Get>d__0.MoveNext() - Thread name: '<Get>d__0.MoveNext()_fc4664d4088d450e8140ad5b943ef1d3'
This proves that original thread exits just before wait. A new thread carries on after the await. So all-in-all 3 threads work in the span of that method.
using System.Diagnostics;
namespace System.Threading
{
public static class ThreadNameTracingExtensions
{
/// <summary>
/// if thread has a name, it leaves the name as it is. If it does not have a name,
/// it sets the thread's name to the module.method
/// It outputs as
/// </summary>
/// <param name="thread"></param>
public static void TraceName(this Thread thread)
{
TraceName(thread, string.Empty);
}
public static void TraceName(this Thread thread, string label)
{
var st = new StackTrace(new StackFrame(1));
var methodBase = st.GetFrame(0).GetMethod();
string frameName = string.Format("{0}.{1}()", methodBase.ReflectedType.Name, methodBase.Name);
Trace.WriteLine(string.Format("{0}{1} - Thread name: '{2}'",
string.IsNullOrEmpty(label) ? "" : string.Format(" Label: {0} |", label),
frameName, thread.Name));
if (string.IsNullOrEmpty(thread.Name))
thread.Name = frameName + "_" + Guid.NewGuid().ToString("N");
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
namespace MvcApplication1.Controllers
{
public class ValuesController : ApiController
{
// GET api/values
public async Task<IEnumerable<string>> Get()
{
Thread.CurrentThread.TraceName("Before await");
await DoWaitAsync();
Thread.CurrentThread.TraceName("After await");
doWork();
Thread.CurrentThread.TraceName("After dowork");
return new string[] { "value1", "value2" };
}
private Task DoWaitAsync()
{
return
Task.Factory.StartNew(
() =>
{
Thread.CurrentThread.TraceName("Inside async");
Thread.Sleep(1000);
Thread.CurrentThread.TraceName("Inside async after sleep");
});
}
public void doWork()
{
Thread.CurrentThread.TraceName("Beginning dowork");
//Not null, runs perfectly fine
var httpCtx = System.Web.HttpContext.Current;
Trace.TraceInformation("doWork is running..." + httpCtx.ToString());
Thread.CurrentThread.TraceName("Ending dowork");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment