单击确定后,ContentDialog延迟

问题描述 投票:1回答:2

我有一个帮助器方法,显示一个ContentDialog,其输入框接受字符串数据。我的问题是,在调用者返回字符串之前单击OK需要大约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。

先感谢您。

c# uwp win-universal-app
2个回答
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;
}

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


2
投票

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

例如,您可以尝试这样的事情:

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

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

enter image description here

这将确保用户等待代码完成执行。 (如果您使用文本输入执行非常简单的操作,这可能会有点过分)

© www.soinside.com 2019 - 2024. All rights reserved.