Задержка ContentDialog после нажатия кнопки ОК - PullRequest
1 голос
/ 22 марта 2019

У меня есть вспомогательный метод, который показывает ContentDialog с полем ввода, которое принимает строковые данные. Моя проблема в том, что после нажатия кнопки ОК проходит около 1 секунды, прежде чем вызывающая сторона возвращает строку (и это очень заметно). Я предположил, что, возможно, это диалоговое окно затухало, анимация по умолчанию / переход заканчивался до того, как диалог возвращался.

В приведенном ниже коде задержка составляет около 1 секунды между нажатием кнопки «ОК» в диалоговом окне и срабатыванием «return textBox.Text».

    /// <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. Я что-то упустил, что мне нужно установить, или это задержка после нажатия OK на ContentDialog из коробки поведения?

  2. Если это вызвано переходом, можно ли его отключить?

  3. Можно ли как-нибудь ускорить время между нажатием кнопки ОК и ожиданием возврата?

Я работаю против 1809 Build 17763.379.

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 23 марта 2019

Следующее решение не является исправлением производительности, поскольку в размещенном вами коде нет ничего плохого.Основная идея заключается в том, что, поскольку этот процесс занимает некоторое время на основе устройства, вы можете просто показать экран вращения / загрузки непосредственно перед вызовом метода ShowInput() и скрыть его после того, как вы закончите, используя значение / текст, возвращаемый ShowInput().

Например, вы можете попробовать что-то вроде этого:

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

Где showLoader / hideLoader будет показывать или скрыть легкий экран загрузчика что-то вродеэто:

enter image description here

Это гарантирует, что пользователь будет ждать, пока код не завершит выполнение.(Это может быть излишним, если вы делаете что-то очень тривиальное с вводом текста)

1 голос
/ 22 марта 2019

Поскольку Pratyay упоминается в его комментарии, количество времени будет зависеть от устройства.

Но что касается ключевого слова await, я считаю, что то, что вы испытываете, является предполагаемым поведением.

Оператор ожидания применяется к задаче в асинхронном методе, чтобы вставить точку приостановки при выполнении метода до завершения ожидаемой задачи. Задача представляет текущую работу.

Источник @ 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;
}

Редактировать: выполнение этого пути больше не требует дополнительного ожидания, поскольку создаваемая задача имеет конечный результат.

...