I have a method, that checks if a button can be pressed or not, if my file path or the language is null, I don't enable the button, and of course, when my file path is selected, I raise the event.
So right now I am doing some work on Azure, and I want to disable the button when I start my work and enable it when I finished my work.
I tried to raise the event, before the call o the method and after the call, but it doesn't enable the button
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);
}
}
When I start working, I execute this code
Many thanks
CodePudding user response:
If the below refactorings don't help, debug your program:
- check if
CanStartAction
is actually called and returns the expected result. - probably the asynchronous method returns too fast for your eye to see the button being disabled. Modify your code as follows to test this:
await AzureTranscription.ConvertToTextAsync(ConvertedAudioPath,
SelectedItem, DocumentName);
await Task.Delay(TimeSpan.FromSeconds(5));
In general, move the RaiseCanExecuteChanged
request to the relevant property setters to keep your code clean.
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;
...
}