如何实施和异步电子邮件验证逻辑?

时间:2016-06-28 20:39:51

标签: c# .net xamarin xamarin.forms mobile-development

我需要实现以下内容:我有一个用户输入电子邮件的页面。每次文本更改时,我都要检查用户是否存在于数据库中并根据该信息,我应该将按钮的文本设置为“注册”或“登录”。问题是,这个DB请求可能需要几秒钟(原因是无关紧要的)并且API是异步的,因此事件处理程序将使用async进行修饰,并且由于邮件条目可能会多次更改,因此该处理程序在任何人结束之前会被召唤好几次。所以我会有并发的API请求,然后可能会同时尝试更改按钮文本,这可能不会很好。我想到了这样的事情:

private async void OnTextChanged(object sender, TextChangedEventArgs e)
{
    mailEntry.TextChanged -= OnTextChanged;
    ...
        submitButton.Text = (await api.AccountExistAsync(mailEntry.Text)).IsRegistered
                            ? "Sign in"
                            : "Sign up";
    ...
    mailEntry.TextChanged += OnTextChanged;
}

但是,这个设计的一个问题是,在-= OnTextChanged+= OnTextChanged之间输入了有效的电子邮件,在这种情况下,它永远不会被检查。

我的问题是,实现我想要实现的目标的正确方法是什么?提前谢谢。

1 个答案:

答案 0 :(得分:0)

这是一个解决方案:

private long requestNumber;

private async void OnTextChanged(object sender, TextChangedEventArgs e)
{
    var text = mailEntry.Text;

    long myRequestNumber = ++requestNumber;

    await Task.Delay(200);

    if (requestNumber != myRequestNumber)
        return;

    var result = (await api.AccountExistAsync(text)).IsRegistered;

    if (requestNumber != myRequestNumber)
        return;

    submitButton.Text = result ? "Sign in" : "Sign up";
}

它维护一个requestNumber变量来保存最后一个请求编号,每次更改文本时都会增加。

如果在AccountExistAsync操作完成后代码发现变量已更改,则会断定已发出新请求,并且不会更新UI。

请注意,解决方案还会在尝试发送验证请求之前等待200毫秒。虽然这会将验证操作延迟200毫秒,但它会阻止发送太多请求,尤其是在用户快速键入时。这当然是可选的。

修改 我在读取/更新requestNumber时删除了同步的使用,因为此类代码仅在UI线程中运行。