C# 如何在Xamarin.Forms中实现异步计时器

C# 如何在Xamarin.Forms中实现异步计时器,c#,asynchronous,xamarin,xamarin.forms,C#,Asynchronous,Xamarin,Xamarin.forms,我正在用Xamarin.Forms实现一个录音机。应该有一个计时器显示记录器运行的时间。点击图像时,录制开始,如果用户再次点击,录制停止。点击的命令代码如下所示: /// <summary> /// The on tabbed command. /// </summary> private async void OnTappedCommand() { if (this.isRecording)

我正在用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
        }
    }
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线程上运行,并且尝试更新UI绑定的TimerValue属性,因为使用了ConfigureWait(false);


2。在这段代码中,您建议在哪里使用Task.Run(),还是根本不应该使用它?

1-它可以工作,因为计时器将在UI线程(主线程)中运行代码。 Device.BeginInvokeOnMainThread()也使用相同的方法。 当您的代码用完UI线程时,您可以使用它(请参阅下一个答案)

2-在您的示例中不应该使用它吗?因为this.TimerValue是由UI线程创建的(并且是该线程的属性) Task.Run()在“线程池”中执行代码,不能接触“UI线程”创建的对象。
“线程池”用于长作业,不应与UI交互。

1)编译器警告您,
StartTimer
同步运行;不要忽视它。2)
Device.StartTimer
的作用是什么?我建议使用System.Diagnostics.Stopwatch计算记录时间,因为您的方法将导致错误的时间值。