Is it allowed to fire ErrorsChanged
event from a non-UI thread? I'm looking at the following article:
Validating Data in WPF 4.5 Using the INotifyErrorDataError Interface.
Particularly, I have a question about this code fragment:
private async void ValidateUsername(string username)
{
const string propertyKey = "Username";
ICollection<string> validationErrors = null;
/* Call service asynchronously */
bool isValid = await Task<bool>.Run(() =>
{
return _service.ValidateUsername(username, out validationErrors);
})
.ConfigureAwait(false);
if (!isValid)
{
/* Update the collection in the dictionary returned by the GetErrors method */
_validationErrors[propertyKey] = validationErrors;
/* Raise event to tell WPF to execute the GetErrors method */
RaiseErrorsChanged(propertyKey);
}
else if(_validationErrors.ContainsKey(propertyKey))
{
/* Remove all errors for this property */
_validationErrors.Remove(propertyKey);
/* Raise event to tell WPF to execute the GetErrors method */
RaiseErrorsChanged(propertyKey);
}
}
Note how ConfigureAwait(false)
is used to allow continuation on a pool thread after await Task<bool>.Run
:
This most likely will lead to ErrorsChanged
event being fired on a non-UI thread. Which is in contrary to MSDN:
The implementing class should raise this event on the user interface thread whenever the
GetErrors
return value changes, even if the return value implementsINotifyCollectionChanged
.
The article seems to have come from a credible source, apparently the code has been tested.
Am I missing something? Is it a bug, or does WPF 4.5 account for this, similar to PropertyChanged
?
I would consider this a bug. Then again, I always raise PropertyChanged
on the UI thread, too; because even though WPF happens to handle it, other MVVM frameworks may not.
Of course, ideally the service would be asynchronous (since it's I/O-bound), and in that case there would be no need for Task.Run
either. Oh, and the sample currently uses an async void
method, which will raise an application-level error if anything untoward happens (e.g., if the validation service is unavailable).
Also, anytime you do something asynchronous with the user's input, you really need to think through the user experience regarding delays and errors. In particular, I'd prefer a solution that displayed an inline busy indicator or something so the user knows the field is being validated. Then it can change to a green check or red x or something when the validation completes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With