0

Is it safe to set a property on an object within an async method and then access that property in the caller after the method has been awaited? Or are locks required? My understanding is that the async state machine would ensure this but all examples I've seen use return values from the async method not properties on a passed in parameter or members within the containing class.

class TestClass
{
    string Member {get; set; }

    public class Parameter
    {
        public string Property { get; set; }
    }

    public async Task MethodAsync(Parameter parameter)
    {
        await Task.Delay(1000);
        Member = "Completed";
        parameter.Property = "Completed";
    }

    public async Task RunTestAsync()
    {
        Member = "Started";
        var parameter = new Parameter()
        {
            Property = "Started"
        };

        await MethodAsync(parameter);
        Console.WriteLine(Member); // Thread safe? Guaranteed to be Completed?
        Console.WriteLine(parameter.Property); // Thread safe? Guaranteed to be Completed?
    }
}
Jonesopolis
  • 25,034
  • 12
  • 68
  • 112
Kris
  • 179
  • 2
  • 10
  • yeah, you're good – Jonesopolis Jun 08 '22 at 18:29
  • 2
    It's safe but you are now relying on the caller to `await` the method. Why not return the updated value instead? That way, you know everything is good. It is also much clearer to the callee what the *intention* of that method is. – DavidG Jun 08 '22 at 18:30
  • 1
    Related: [Are you there, asynchronously written value?](https://stackoverflow.com/questions/28871878/are-you-there-asynchronously-written-value) – Theodor Zoulias Jun 08 '22 at 18:32
  • The idea with `await` and `Task.Wait` is that you block execution until that action is completed, so any property updates you make within those actions would be safe to call and assumed to be the most recent data. Conversely, if you didn't use `await`, then it is possible for the order of operations to result in `Member` being set after you try to call it. – Ibrennan208 Jun 08 '22 at 18:34
  • 1
    Thank you for your quick comments, I should have used the term Memory Barriers as well to be more clear as that is the main focus of the question. @TheodorZoulias has linked a very similar if not duplicate question, thank you for sharing that one I never found it myself. – Kris Jun 08 '22 at 18:41
  • @DavidG 99.999% of the time I use return values only, but there have been times where it would be nice to use a parameter and I always wondered then if the async state machine would also ensure their values are set. – Kris Jun 08 '22 at 18:45

0 Answers0