Given a simple Hotel entity as an example:
class Hotel
{
public int NumberOfRooms { get; set; }
public int StarRating { get; set; }
}
Please consider the following code in C# 5.0:
public void Run()
{
var hotel = new Hotel();
var tasks = new List<Task> { SetRooms(hotel), SetStars(hotel) };
Task.WaitAll(tasks.ToArray());
Debug.Assert(hotel.NumberOfRooms.Equals(200));
Debug.Assert(hotel.StarRating.Equals(5));
}
public async Task SetRooms(Hotel hotel)
{
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
hotel.NumberOfRooms = 200;
}
public async Task SetStars(Hotel hotel)
{
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
hotel.StarRating = 5;
}
Both calls to Debug.Assert() pass successfully. I don't understand how after both tasks have completed, the instance of Hotel contains the assignment from both the methods that run in parallel.
I thought that when await
is called (in both SetRooms()
and SetStars()
), a "snapshot" of the hotel instance is created (having both NumberOfRooms
and StarRating
set to 0). So my expectation was that there will be a race condition between the two tasks and the last one to run will be the one copied back to hotel
yielding a 0 in one of the two properties.
Obviously I am wrong. Can you explain where I'm misunderstanding how await works?