I'm implementing an audio recorder in Xamarin.Forms. There should be a timer displaying the time the recorder is running. On tapping on a image, the recording starts, and if the user taps again, the recording stops. The tapped command code looks like:
/// <summary>
/// The on tabbed command.
/// </summary>
private async void OnTappedCommand()
{
if (this.isRecording)
{
this.isRecording = false;
await this.StopRecording().ConfigureAwait(false); // Stops the MediaRecorder
}
else
{
this.isRecording = true;
await this.StartTimer().ConfigureAwait(false); // Starts the Timer
await this.StartRecording().ConfigureAwait(false); // Starts the MediaRecorder
}
}
The StartTimer() method looks like:
private async Task StartTimer()
{
Device.StartTimer(
new TimeSpan(0, 0, 0, 0, 1),
() =>
{
if (this.isRecording)
{
Device.BeginInvokeOnMainThread(
() =>
{
this.TimerValue = this.TimerValue + 1;
});
return true;
}
Device.BeginInvokeOnMainThread(
() =>
{
this.TimerValue = 0;
});
return false;
});
}
The TimerValue is a simple integer property bound to a label that's using a ValueConverter to handle the formatting.
My Questions are:
1. Why does my code work even if I remove the Device.BeginInvokeOnMainThread method? Shouldn't it throw an error because it's not running on the UI-Thread and trying to update the UI-Bound TimerValue Property, since ConfigureAwait(false) is used?
2. Where do you suggest to use Task.Run() in this code, or should'nt it be used at all?
StartTimer
runs synchronously; don't ignore it. 2) What doesDevice.StartTimer
do? – Stephen Cleary