C# 异步方法的布尔检查

C# 异步方法的布尔检查,c#,uwp,C#,Uwp,我想检查文本框是否为空,然后使用MessageDialog向用户发出错误警告。我的问题是异步方法需要一个void返回类型,所以我不能使用bool来检查CheckEmpty是否返回true或false。当出现错误/消息警告时,如何停止AddButton_Click after CheckEmpty()中的代码 public void AddButton_Click(object sender, RoutedEventArgs e) { if (roleComboBox.Se

我想检查文本框是否为空,然后使用MessageDialog向用户发出错误警告。我的问题是异步方法需要一个void返回类型,所以我不能使用bool来检查CheckEmpty是否返回true或false。当出现错误/消息警告时,如何停止AddButton_Click after CheckEmpty()中的代码

public void AddButton_Click(object sender, RoutedEventArgs e)
    {
        if (roleComboBox.SelectionBoxItem.Equals("Player"))
        {
            CheckEmpty();
            memberID++;

            Player player = new Player(memberID, team, firstName, lastName, age, salary, yearsActive, position, minutesPerGame);

            players.Add(player);

            idBox = idComboBox;
            idBox.Items.Add(memberID);

            PrintList();
        }
    }


private async void CheckEmpty()
    {
        if (firstNameTextBox.Text == "") //if (String.IsNullOrEmpty(firstNameTextBox.Text) 
        {
            var messageDialog = new MessageDialog("Text here");
            messageDialog.Commands.Add(new UICommand("Try again"));
            await messageDialog.ShowAsync();
        }

CheckEmpty
可以返回一个
任务
,为了符合约定,应该重命名为
CheckEmptyAsync

private async Task<bool> CheckEmptyAsync()
{
    if (firstNameTextBox.Text == "") //if (String.IsNullOrEmpty(firstNameTextBox.Text) 
    {
        var messageDialog = new MessageDialog("Text here");
        messageDialog.Commands.Add(new UICommand("Try again"));
        await messageDialog.ShowAsync();

        return true;
    }

    return false;
}
public async void AddButton_Click(object sender, RoutedEventArgs e)
{
    if (roleComboBox.SelectionBoxItem.Equals("Player"))
    {
        if (await CheckEmptyAsync())
        {
            return;
        }

        // ...
    }
}

或者,在这种情况下,放弃由
showascync
返回的
Task
并同步运行代码不会造成实际伤害:

private bool CheckEmpty()
{
    if (firstNameTextBox.Text == "") //if (String.IsNullOrEmpty(firstNameTextBox.Text) 
    {
        var messageDialog = new MessageDialog("Text here");
        messageDialog.Commands.Add(new UICommand("Try again"));
        _ = messageDialog.ShowAsync();

        return true;
    }

    return false;
}
您可以返回一个任务

如果您的代码(“检查器”)抛出异常,则不需要执行
任务
。这是一个有点灰色的决定
Task
vs Task

但这是唯一的选择

您可以在这里看到一个类似的示例:(这是第三个选项的
Task

请注意,MS文章示例

private async void StartButton_Click(object sender, RoutedEventArgs e)
但同时也有这个(矛盾的)建议:

空虚。 对于事件处理程序以外的代码,通常不鼓励使用异步void方法,因为调用方不能等待这些方法,必须 实施不同的机制以报告成功完成或 错误条件

但它们提供了以下提示:

您主要使用void返回类型来定义事件处理程序,它 需要该返回类型。void返回异步方法的调用方 无法等待它,也无法捕获该方法引发的异常

因此,微软的文章解释了为什么他们使用的代码与非最佳实践建议之间存在差异

从哲学上讲,你可以读到这一点

即:


“通过抛出异常来报告执行失败。”

最简单的解决方案是使用异步任务,这允许异步方法返回值

        private async Task<bool> CheckEmptyAsync()
        {
            //its also good practice to put the constants on the left hand side 
            if (string.Empty == firstNameTextBox.Text)
            {
                await (new MessageDialog("Text here")).Commands.Add(new UICommand("Try again"))).ShowAsync();
                return true;
            }
            return false;
        }
private异步任务CheckEmptyAsync()
{
//将常数放在左手边也是一个很好的做法
if(string.Empty==firstNameTextBox.Text)
{
wait(新建MessageDialog(“此处文本”)).Commands.Add(新建UICommand(“重试”))).ShowAsync();
返回true;
}
返回false;
}

为什么
CheckEmpty()
需要是
Void
?“异步Void”永远不会这样做,99.9%的时间,仅供参考@granadaCoder告诉某人,当他们提供的代码值得执行时,不要执行某些操作不是一个好主意。你甚至做了你在回答这个问题时说过永远不应该做的事情。所以我模仿了微软的例子(因为如果你只留下一个链接,这不是软件的最佳实践)。微软的例子有“私有异步void StartButton_Click(objectsender,RoutedEventArgs e)”,但同样的微软文章也有“无效。对于事件处理程序以外的代码,通常不鼓励使用异步void方法,因为调用方不能等待这些方法,必须实现不同的机制来报告成功完成或错误情况。“我对JB的答案投了更高的票……但我给出的答案与问题密切相关,并且与ms的例子非常相似。上一篇评论中的链接我不理解这行:u=messageDialog.ShowAsync();您能详细说明一下吗?@DannyRoulaux
\uuu
是一个,它是在C#7中引入的,并明确表示您忽略了
messageDialog.ShowAsync()
返回的值(即
Task
)。代码将编译并以相同的方式工作,没有丢弃,但它表明您已做出有意识的决定,不等待
任务的完成。Thx,我不知道丢弃。也谢谢你的链接,我现在就来研究一下。
        private async Task<bool> CheckEmptyAsync()
        {
            //its also good practice to put the constants on the left hand side 
            if (string.Empty == firstNameTextBox.Text)
            {
                await (new MessageDialog("Text here")).Commands.Add(new UICommand("Try again"))).ShowAsync();
                return true;
            }
            return false;
        }