我正在用Xamarin.Forms实现录音机。应该有一个显示记录器运行时间的计时器。在点击图像时,录制开始,如果用户再次点击,则录制停止。点击的命令代码如下所示:
/// <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
}
}
StartTimer()方法如下所示:
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;
});
}
TimerValue 是绑定到标签的简单整数属性,该标签使用ValueConverter来处理格式。
我的问题是:
1。即使我删除了Device.BeginInvokeOnMainThread方法,为什么我的代码也能正常工作?它不应该抛出错误,因为它没有在UI-Thread上运行并尝试更新UI-Bound TimerValue属性,因为使用了ConfigureAwait(false)?
2。你在哪里建议在这段代码中使用Task.Run(),或者根本不应该使用它?
答案 0 :(得分:0)
1-之所以起作用,是因为计时器将在 UI线程(主线程)中运行代码。 与Device.BeginInvokeOnMainThread()使用的相同。 当您的代码用完 UI线程(请参阅下一个答案)
时,可以使用它2-在您的示例中完全不应使用它,因为this.TimerValue是由 UI线程创建的(并且是其属性) Task.Run()在“线程池”中执行代码,并且无法触摸由“ UI线程”创建的对象。 “线程池”将用于较长的作业,并且不应与UI交互。