【问题标题】:How to implement an async timer in Xamarin.Forms如何在 Xamarin.Forms 中实现异步计时器
【发布时间】:2017-05-16 17:59:20
【问题描述】:

我正在 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 方法,我的代码仍然有效?由于使用了 ConfigureAwait(false),它不应该抛出错误,因为它没有在 UI-Thread 上运行并尝试更新 UI-Bound TimerValue 属性吗?

2。您建议在此代码中的何处使用 Task.Run(),或者根本不应该使用它?

【问题讨论】:

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

标签: c# asynchronous xamarin xamarin.forms


【解决方案1】:

1 - 之所以有效,是因为计时器将在 UI 线程(主线程)中运行代码。 Device.BeginInvokeOnMainThread() 使用的相同。 您可以在您的代码用完 UI 线程 时使用它(请参阅下一个答案)

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

【讨论】:

    猜你喜欢
    • 2013-09-09
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多