简体   繁体   English

WPF 4.5中的INotifyDataErrorInfo和异步数据验证

[英]INotifyDataErrorInfo and asynchronous data validation in WPF 4.5

Is it allowed to fire ErrorsChanged event from a non-UI thread? 是否允许从非UI线程触发ErrorsChanged事件? I'm looking at the following article: 我正在看以下文章:

Validating Data in WPF 4.5 Using the INotifyErrorDataError Interface . 使用INotifyErrorDataError接口验证WPF 4.5中的数据

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 : 注意在等待Task<bool>.Run之后,如何使用ConfigureAwait(false)允许在池线程上继续:

This most likely will lead to ErrorsChanged event being fired on a non-UI thread. 这很可能会导致在非UI线程上触发ErrorsChanged事件。 Which is in contrary to MSDN: 这与MSDN相反:

The implementing class should raise this event on the user interface thread whenever the GetErrors return value changes, even if the return value implements INotifyCollectionChanged . 只要GetErrors返回值发生更改,实现类就应该在用户界面线程上引发此事件,即使返回值实现了INotifyCollectionChanged

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 ? 这是一个错误,或WPF 4.5是否与此相关, 类似于PropertyChanged

I would consider this a bug. 我认为这是一个错误。 Then again, I always raise PropertyChanged on the UI thread, too; 然后,我总是在UI线程上提出PropertyChanged ; because even though WPF happens to handle it, other MVVM frameworks may not. 因为即使WPF碰巧处理它,其他MVVM框架也可能不会。

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. 当然,理想情况下,服务将是异步的(因为它是I / O绑定的),在这种情况下,也不需要Task.Run Oh, and the sample currently uses an async void method, which will raise an application-level error if anything untoward happens (eg, if the validation service is unavailable). 哦,并且示例当前使用async void方法,如果发生任何不幸事件(例如,如果验证服务不可用),则会引发应用程序级错误。

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. 然后它可以在验证完成时更改为绿色检查或红色x或其他内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM