单击“确定”后的 ContentDialog 延迟

ContentDialog delay after OK clicked

我有一个辅助方法,它显示一个带有接受字符串数据的输入框的 ContentDialog。我的问题是,在调用者取回字符串之前单击“确定”大约需要 1 秒(这非常明显)。我推测可能是对话框在对话框返回之前淡出默认 animation/transition 结束。

在下面的代码中,在对话框中单击“确定”与触发 "return 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. 有什么方法可以加快单击“确定”和等待 returns 之间的时间?

我运行反对1809 Build 17763.379。

提前致谢。

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

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

The await operator is applied to a task in an asynchronous method to insert a suspension point in the execution of the method until the awaited task completes. The task represents ongoing work.

Source @ Microsoft Doc

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

所以尽管您的 ShowInput 函数应该 return 几乎立即。您会注意到 dialog.ShowAsync();return textBox.Text; 之间的延迟。

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

Is there anyway I can speed up the time between when OK is clicked and the await returns?

我认为获得响应的最快方法是不等待 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;
}

编辑:这样做不再需要额外的等待,因为正在创建的任务中有最终结果。

以下解决方案并不是真正的性能修复,因为您发布的代码没有任何问题。 基本思想是 - 由于此过程需要一段时间,具体取决于设备,您可以在调用 ShowInput() 方法之前显示微调器/加载屏幕,并在使用 value/text 完成后隐藏它ShowInput().

返回

例如,您可以尝试这样的操作:

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

其中 showLoader/hideLoader 将 显示隐藏 轻量级加载程序屏幕,如下所示:

这将确保用户等待代码执行完毕。 (如果您正在对文本输入做一些非常微不足道的事情,这可能有点矫枉过正)