单击确定后,ContentDialog延迟

时间:2019-03-22 18:35:56

标签: c# uwp win-universal-app

我有一个帮助程序方法,该方法显示一个ContentDialog以及一个接受字符串数据的输入框。我的问题是,单击“确定”后大约需要1秒钟,调用者才能返回字符串(这非常明显)。我认为,可能是该对话框淡出了默认的动画/过渡,在对话框返回之前结束。

在下面的代码中,单击对话框上的“确定”与触发“返回textBox.Text”之间存在大约1秒钟的延迟。

    /// <summary>
    /// Shows an simple input box to get a string value in return.
    /// </summary>
    /// <param name="title">The title to show at the top of the dialog.</param>
    /// <param name="message">The message shown directly above the input box.</param>
    /// <param name="defaultValue">A value to prepopulate in the input box if any.</param>
    /// <returns></returns>
    public static async Task<string> ShowInput(string message, string defaultValue, string title)
    {
        var dialog = new ContentDialog
        {
            Title = title
        };

        var panel = new StackPanel();
        panel.Children.Add(new TextBlock { Text = message, TextWrapping = Windows.UI.Xaml.TextWrapping.Wrap });

        var textBox = new TextBox();
        textBox.Text = defaultValue;
        textBox.SelectAll();

        textBox.KeyUp += (o, e) =>
        {
            if (e.Key == Windows.System.VirtualKey.Enter)
            {
                dialog.Hide();
            }

            e.Handled = true;
        };

        panel.Children.Add(textBox);

        dialog.Content = panel;
        dialog.PrimaryButtonText = "OK";            
        await dialog.ShowAsync();

        return textBox.Text;
    }

我的问题是:

  1. 我错过了应该设置的内容吗?还是在ContentDialog上单击“确定”后出现了这种延迟?

  2. 如果是由于过渡引起的,可以禁用它吗?

  3. 无论如何,我可以加快单击OK到等待返回之间的时间吗?

我正在反对1809 Build 17763.379。

谢谢。

2 个答案:

答案 0 :(得分:2)

以下解决方案并不是真正的性能修复,因为您发布的代码没有错。 基本思想是-由于此过程需要一段时间才能根据设备而定,因此您只需在调用ShowInput()方法之前显示微调框/加载屏幕,并在使用完后返回的值/文本后将其隐藏即可ShowInput()

例如,您可以尝试如下操作:

showLoader();
string x = await ShowInput("message","","title");
...
//some more code 
...
hideLoader();

在showLoader / hideLoader将显示或显示隐藏轻量级加载器屏幕的地方,如下所示:

enter image description here

这将确保用户等待代码完成执行。 (如果您对文本输入做一些琐碎的操作,这可能会显得过分杀伤)

答案 1 :(得分:1)

正如Pratyay在他的评论中提到的,时间的长短因设备而异。

但是就await关键字而言,我相信您所遇到的是预期的行为。

  

将await运算符应用于异步方法中的任务,以在该方法的执行中插入一个挂起点,直到等待的任务完成为止。该任务代表正在进行的工作。

     

Source @ Microsoft Doc

这意味着您的ShowInput函数将在到达Task<string>关键字后立即返回其await对象。然后,在dialog.ShowAsync();返回之后,它将异步地继续执行ShowInput函数,并将结果放入Task对象中以供您检索。

因此,尽管您的ShowInput函数应几乎立即返回。您会注意到dialog.ShowAsync();return textBox.Text;之间的延迟。

要记住的另一件事是,当窗口关闭时,在窗口循环完成之前通常需要进行一些处理(处理资源等)。编写代码的方式是,您必须等到所有这些完成之后才能得到结果。

  

无论如何,我可以加快单击OK到等待返回之间的时间吗?

我想最快获得回复的方法是不等待ContentDialog,而是等待内容可用时立即发生的信号。

public static Task<string> ShowInput(string message, string defaultValue, string title)
{
    var dialog = new ContentDialog { Title = title };

    var panel = new StackPanel();
    panel.Children.Add(new TextBlock { Text = message, TextWrapping = Windows.UI.Xaml.TextWrapping.Wrap });

    var textBox = new TextBox() { Text = defaultValue };
    textBox.SelectAll();

    var signal = new TaskCompletionSource<string>();

    textBox.KeyUp += (o, e) =>
    {
        if (e.Key == Windows.System.VirtualKey.Enter)
        {
            dialog.Hide();
            signal.SetResult(textBox.Text);
        }

        e.Handled = true;
    };
    dialog.PrimaryButtonClick += (o, e) => 
    {
        dialog.Hide();
        signal.SetResult(textBox.Text);
    };

    panel.Children.Add(textBox);

    dialog.Content = panel;
    dialog.PrimaryButtonText = "OK";            
    dialog.ShowAsync();

    return signal.Task;
}

编辑:以这种方式执行操作不再需要额外的等待,因为正在创建的任务具有最终结果。