У меня есть приложение classi c WinForms, которое обменивается данными asyn c с серверным API. Это реализуется шаблоном asyn c await.
Теперь у меня проблема с событием «Validating». Мы используем это событие для проверки на стороне клиента (проверяем, является ли ввод нулевым) и устанавливаем отмену. Если ввод действителен, я отправляю его на сервер asyn c и жду результата.
Это моя проблема. Теперь контроль означает, что он действителен. Когда обратный вызов устанавливает для события отмены значение false, уже слишком поздно.
Вот мой код:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string CustomerName { get; set; }
private async void Button1_Validating(object sender, CancelEventArgs e)
{
if (CustomerName == null)
{
e.Cancel = true;
}
else
{
var isValidAndSaved = await SaveOnServerAsync(CustomerName);
// Here is the Problem: Setting e.Cancel in callback is too late.
if (isValidAndSaved)
{
e.Cancel = false;
}
else
{
e.Cancel = true;
}
}
}
/// <returns>True if the given model was valid and save operation was successfull.</returns>
public async Task<bool> SaveOnServerAsync(string customerName)
{
await Task.Delay(3000); // Send given customerName to server in real app.
return customerName.Contains("%") ? false : true;
}
}
Я пробовал программировать classi c (синхронно) для этого случая с помощью 'Подождите 'Таксы в основном потоке. Но затем я сгенерировал тупик.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public string CustomerName { get; set; } = "3";
private void Button1_Validating(object sender, CancelEventArgs e)
{
if (CustomerName == null)
{
e.Cancel = true;
}
else
{
// Deadlock because MainThread waits for callback.
var isValidAndSaved = SaveOnServerAsync(CustomerName).Result;
if (isValidAndSaved)
{
e.Cancel = false;
}
else
{
e.Cancel = true;
}
}
}
/// <returns>True if the given model was valid and save operation was successfull.</returns>
public async Task<bool> SaveOnServerAsync(string customerName)
{
await Task.Delay(3000); // Send given customerName to server in real app.
return customerName.Contains("%") ? false : true;
}
}
Есть ли у кого-нибудь идея для хорошего шаблона?
Если я установлю Cancel в false перед ожиданием задачи asyn c, тогда моя проблема будет что пользовательский щелчок отбрасывается и пользовательский опыт достаточен.