问题描述
我在使用异步验证时遇到验证错误的问题。
我正在使用 DevExpress 文本框,并通过验证方法使用异步调用来验证数字是否唯一。其他本地检查显示验证错误 fin,但当我进入第三步(异步)时,它没有显示错误。
我确定这是由于调用的异步性质。我已经尝试使用 async/await、Task.Runin 太多的组合,我数不清了,但仍然无法使其工作。
xaml:
<dxe:TextEdit
EditValue="{Binding Mode=TwoWay,NotifyOnSourceUpdated=True,Path=Dto.Number,updateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"
InvalidValueBehavior="AllowLeaveEditor"
IsEnabled="{Binding IsNew,UpdateSourceTrigger=PropertyChanged}"
NullText="Enter number"
ValidateOnTextInput="True"
Validate="NumberOnValidate" />
xaml.cs
private void NumberOnValidate(object sender,ValidationEventArgs e)
{
if (!((TextEdit) sender).IsEnabled)
{
return;
}
//Task.Run(async () => {
e.ErrorContent = RequiredValidationRule.GetErrorMessage("Number",e.Value);
if (string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
{
e.ErrorContent = StringMaxlengthValidationRule.GetErrorMessage("Number",255,e.Value);
if (string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
{
var dataContext = (UpsertViewModel) DataContext;
Task.Run(async () =>
{
e.ErrorContent = await Validation.IsNumberUnique(dataContext.HubConnection,dataContext.SelectedType,e.Value);
});
}
}
if (!string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
{
e.IsValid = false;
}
//});
}
验证:
public static async Task<string> IsNumberUnique(IHubConnection hubConnection,EnumType type,object fieldValue)
{
if (fieldValue == null || string.IsNullOrWhiteSpace(fieldValue.ToString()))
{
return "Cannot validate the uniqueness of the number field because it is empty.";
}
//Task.Run(async () =>
//{
try
{
var response = false;
switch (type)
{
case EnumType.T1:
response = await hubConnection.T1IsNumberUnique(fieldValue.ToString());
break;
case EnumType.T2:
response = await hubConnection.T2IsNumberUnique(fieldValue.ToString());
break;
case EnumType.T3:
response = await hubConnection.T3IsNumberUnique(fieldValue.ToString());
break;
}
if (!response)
{
return "The number field must be unique.";
}
}
catch (Exception ex)
{
return $"Error validating the number field for uniqueness. Exception: {ex}";
}
return string.Empty;
//});
//return string.Empty;
}
我想我已经尝试了我能想到的所有方法,但是获取异步调用的短暂延迟使得验证方法跳过响应并且它不会在 GUI 中注册。
在调试时,我可以看到在验证发生后异步响应即将到来,那么我如何对齐线程以使验证“等待”异步响应。
解决方法
Task.Run(async () =>
{
e.ErrorContent = await Validation.IsNumberUnique(dataContext.HubConnection,dataContext.SelectedType,e.Value);
});
这段代码触发了另一个线程中的异步任务。您的原始验证线程会在您遇到时立即继续。
我猜您可以阻塞异步方法的 Result,但这会抵消异步的优势,并且会在运行时锁定 UI。
我怀疑您需要做一些很棘手的事情,例如在异步方法完成时再次引发 PropertyChanged,这将强制 WPF 再次验证,并使用某种标志来防止再次运行异步调用。