Отключить кнопку, когда Задача завершена

У меня есть метод, который проверяет, можно ли нажать кнопку или нет, если мой путь к файлу или язык нулевой, я не включаю кнопку, и, конечно, когда мой путь к файлу выбран, я поднимаю событие.

Итак, прямо сейчас я выполняю некоторую работу в Azure и хочу отключить кнопку, когда начинаю свою работу, и включить ее, когда закончу свою работу.

Я пытался вызвать событие до вызова метода и после вызова, но он не включает кнопку

        public string? FilePath { get; set; }

        public bool IsWorking { get; set; }

        public Dictionary<int, Languages>? LanguagesDictionary { get; set; }

        public Visibility CanShow { get; set; }

        public DialogHelper DialogHelper { get; }

        public FolderHelper FolderHelper { get; }

        public AudioHelper AudioHelper { get; }

        public AzureTranscriptionService AzureTranscription { get; }

        public Command PickFileCommad { get; set; }

        public Command StartCommand { get; set; }

        private string? _SelectedItem;

        public string SelectedItem {
            get => _SelectedItem!;
            set {
                if (_SelectedItem != value) {
                    _SelectedItem = value;
                    StartCommand.RaiseCanExecuteChanged();
                }
            }
        }

        public AudioPageViewModel() {
            InitListLanguages();
            AzureTranscription = new AzureTranscriptionService();
            DialogHelper = new DialogHelper();
            FolderHelper = new FolderHelper();
            AudioHelper = new AudioHelper();
            CanShow = Visibility.Hidden;
            PickFileCommad = new Command(PickFileAction);
            StartCommand = new Command(StartAction, CanStartAction);
        }

        private bool CanStartAction(object arg) {
            if (string.IsNullOrEmpty(SelectedItem) ||
                string.IsNullOrEmpty(FilePath) ||
                IsWorking == true) {
                return false;
            }
            return true;
        }

        private async void StartAction(object obj) {

            var FileWithoutExtension = Path.GetFileNameWithoutExtension
                (FilePath);

            var AudioPath = FolderHelper.CreateFolder(ConstantsHelpers.AUDIO);

            var DocumentPath = FolderHelper.CreateFolder();

            var AudioFileNamePath = Path.Combine(AudioPath, $"{FileWithoutExtension}{ConstantsHelpers.WAV}");

            var ConvertedAudioPath = AudioHelper.Converter(FilePath!, AudioFileNamePath);

            var DocumentName = Path.Combine(DocumentPath, $"{FileWithoutExtension}{ConstantsHelpers.DOCX}");

            IsWorking = true;

            StartCommand.RaiseCanExecuteChanged();

            await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath,
                SelectedItem, DocumentName);

            IsWorking = false;
            StartCommand.RaiseCanExecuteChanged();


        }

        private void PickFileAction() {
            var FullPath = DialogHelper.GetFilePath(ConstantsHelpers.AUDIO);
            FilePath = FullPath;

            StartCommand?.RaiseCanExecuteChanged();
        }

 public async Task ConvertToTextAsync(
            string FilePath,
            string Language,
            string WordDocName) {

            // Configure speech service

            var config = SpeechConfig.FromSubscription(ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION);
            config.SpeechRecognitionLanguage = Language;
            // Configure speech recognition

            var taskCompleteionSource = new TaskCompletionSource<int>();

            using var audioConfig = AudioConfig.FromWavFileInput(FilePath);
            using var speechRecognizer = new SpeechRecognizer(config, audioConfig);
            speechRecognizer.Recognizing += SpeechRecognizer_Recognizing;
            speechRecognizer.Recognized += SpeechRecognizer_Recognized;
            speechRecognizer.SessionStarted += SpeechRecognizer_SessionStarted;
            speechRecognizer.SessionStopped += SpeechRecognizer_SessionStopped;

            await speechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);

            Task.WaitAny(new[] { taskCompleteionSource.Task });

            await speechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
        }

        private void SpeechRecognizer_SessionStopped(object? sender, SessionEventArgs e) {

            Debug.WriteLine("Stepped");
            var sb = new StringBuilder();

            foreach (var item in Letters) {
                sb.Append(item);
            }
        }

        private void SpeechRecognizer_SessionStarted(object? sender, SessionEventArgs e) {

            Debug.WriteLine("Started");
        }
        private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e) {
            if (e.Result.Reason == ResultReason.RecognizedSpeech) {
                foreach (var item in e.Result.Text) {
                    Letters.Add(item);
                }
            }
        }

        private void SpeechRecognizer_Recognizing(object? sender, SpeechRecognitionEventArgs e) {

            Debug.WriteLine(e.Result.Text);
        }
    }

Когда я начинаю работать, я выполняю этот код

Большое спасибо

Task.Wait и Task.WaitAny приведут к потенциальной взаимоблокировке и принудительному синхронному выполнению. Вы всегда должны использовать await, чтобы дождаться завершения задачи. Эквивалентный асинхронный фрагмент: await Task.WhenAny. Как только ожидаемая задача возвращается, вы можете установить флаг, который проверяется делегатом CanExecute ICommand, привязанным к кнопке. Если CanExecute вернет false, кнопка отключится.
BionicCode 22.10.2022 17:24

Не могли бы вы предоставить фрагмент кода

edu 22.10.2022 17:26

Вы не предоставили достаточно кода, чтобы привести пример. Просто введите частное логическое свойство. Затем подождите ConvertToTextAsync. Затем, когда ожидание продолжится, установите для этого свойства значение false. Позвольте CanExecute делегату ICommand проверить это свойство.

BionicCode 22.10.2022 17:30

Какая информация вам нужна

edu 22.10.2022 17:34

именно поэтому я создал isWorking

edu 22.10.2022 17:35

Как реализована команда. Использует ли он CommandManager?

BionicCode 22.10.2022 17:44

Давайте продолжим обсуждение в чате.

edu 22.10.2022 17:44

Также убедитесь, что ваш CanStartAction возвращает правильное значение.

BionicCode 22.10.2022 17:58

Что вы имеете в виду, возвращая соответствующее значение, это метод, связанный с кнопкой

edu 22.10.2022 18:06

Для чего нужен TaskCompletionSource? Вы не используете его.

BionicCode 22.10.2022 19:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если приведенные ниже рефакторинги не помогают, отладьте свою программу:

  • проверьте, действительно ли CanStartAction вызывается и возвращает ожидаемый результат.
  • вероятно, асинхронный метод возвращается слишком быстро, чтобы вы могли увидеть, что кнопка отключена. Измените свой код следующим образом, чтобы проверить это:
await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath,
                SelectedItem, DocumentName);
await Task.Delay(TimeSpan.FromSeconds(5));

В общем, переместите запрос RaiseCanExecuteChanged в соответствующие установщики свойств, чтобы ваш код оставался чистым.


private bool isBusy;
private bool IsBusy 
{ 
  get => this.isBusy; 
  set
  {
    this.isBusy = value;
    this.StartCommand.RaiseCanExecuteChanged();
  }
}

private bool CanStartAction(object arg) 
{
  return !string.IsNullOrEmpty(SelectedItem) &&
    !string.IsNullOrEmpty(FilePath) &&
    !this.IsBusy
}

private async void StartAction(object obj) 
{ 
  this.IsBusy = true;

  var fileWithoutExtension = Path.GetFileNameWithoutExtension
                (FilePath);
  var audioPath = FolderHelper.CreateFolder(ConstantsHelpers.AUDIO);
  var documentPath = FolderHelper.CreateFolder();
  var audioFileNamePath = Path.Combine(audioPath, $"{FileWithoutExtension}{ConstantsHelpers.WAV}");
  var convertedAudioPath = AudioHelper.Converter(FilePath!, audioFileNamePath);
  var documentName = Path.Combine(documentPath, $"{fileWithoutExtension}{ConstantsHelpers.DOCX}");

  await AzureTranscription.ConvertToTextAsync(convertedAudioPath,
                this.SelectedItem, documentName);

  this.IsBusy = false;
}

public async Task ConvertToTextAsync(string FilePath,
  string Language,
  string WordDocName) 
{
  ...
  
  // Using Task.Wait, Task.WaitAny and Task.WaitAll will execute a Task synchronously and introduces a potential deadlock.
  // To avoid this, always await a Task and use Task.WhenAny and Task.WhenAll instead
  await Task.WhenAny(new[] { taskCompleteionSource.Task });
  
  // Or because you only have to wait for a single Task write
  await taskCompleteionSource.Task;

  ...
}

См. Рекомендации по именованию C#

Спасибо, но кнопка не активируется

edu 22.10.2022 20:30

Извините, все работает нормально, мне нужно выяснить, почему мой метод Azure не работает.

edu 22.10.2022 20:36

Извините, но я не минусовал ваш пост. Я бы попросил вас опубликовать новый вопрос, связанный с вашим вызовом API Azure. Это не связано с этим вопросом.

BionicCode 22.10.2022 20:56

Как правило, при использовании любых служб, таких как службы Azure или Google, убедитесь, что ваше приложение правильно аутентифицировано.

BionicCode 22.10.2022 20:59

Другие вопросы по теме