I have a question and want to know best practice we need to follow for async function. I have two function in my view model and they are being called from the setter of property. These two function are async void but we want to convert them to async of task as async void is a smell for bad code. But setter property does not allow us to await. So i wanted to know from where should I call these two function we also do not want to do this from the constructor as there also we can not await the fuction and contructor is not for this purpose. I just want to know the best practice to avoid calling async task function from property. I want to set and populate the data on property change so we are calling async function from property.
-
1Can you please provide some code? – virouz98 Feb 25 '22 at 07:55
-
11 line of code is worth a 1000 words. Please add it as text, not image. – Fildor Feb 25 '22 at 07:56
-
If calling `object.Name` will start asynchronous action, I would be very surprised. Call it before creating an object and set values before usage. – Fabio Feb 25 '22 at 07:58
-
A async property is strange. Rather convert it so an async method. Properties are properties, some validation could take place, but not big chunks of code. – Jeroen van Langen Feb 25 '22 at 08:04
2 Answers
I just want to know the best practice to avoid calling async task function from property.
Simple; don't. Instead of a property, consider a method instead property getters/setters are really just regular methods that follow a convention anyway - and that convention does not and can not apply for async code.
So: instead of:
public string Something
{
get => ???
set => ???
}
consider:
public [async] Task<string> GetSomething() => // whatever you need here
public [async] Task SetSomething(string value) => // whatever you need here

- 1,026,079
- 266
- 2,566
- 2,900
As Marc already suggested, I would avoid such properties and turn them to functions, because when calling get/set of a property I expect it to be a fast and light operation which I can do very often without consequences (and an async operation indicates a more heavy operation).
Turning it to a function gives a hint to other devs, that this may come with costs. It is also possible to keep a readonly property and write a dedicated function with a good name to change it.
public int MaxLength
{
get { return _maxLength; }
}
public async Task RestrictToMaxLength(int maxLength)
{
await DoWhateverIsNecessary(maxLength);
_maxLength = maxLength;
}

- 23,430
- 6
- 56
- 87
-
I want to know if lets take maxlength and it is changeable from ui also And if a user changes maxlength to certain value. I want to understand how to invoke function that is async when maxlength changes. – mish Feb 25 '22 at 09:36
-
@mish - So your problem is databinding/MVVM with the GUI? The binding only works with properties, and to inform the GUI about changes you have to use the `INotifyPropertyChanged` interface. In this case a property may indeed be the easiest solution, there is another [discussion](https://stackoverflow.com/q/6602244/575765) about this topic. – martinstoeckli Feb 25 '22 at 10:53