【问题标题】:Parellel Task Library vs UI Thread Xamarin.Forms when constantly updating the UI不断更新 UI 时的并行任务库与 UI 线程 Xamarin.Forms
【发布时间】:2017-05-01 07:33:30
【问题描述】:

我正在尝试在 Xamarin Forms 中制作秒表,并且想知道是否应该使用本机 UI 线程或并行任务库来不断更新时间标签?

我尝试使用 PT Lib,但无法让它更新我的标签,这让我认为我应该使用本机线程,但我担心我是否能够更新 UI使用依赖服务。

是否有一种最佳做法是不断更新 UI,但仍能执行其他任务,例如单击按钮?


更新:我得到了下面的代码,但这是一种好的做法吗?我不断更新时间标签,同时还能按圈按钮。

Stopwatch sw = new StopWatch();
bool inRace = false;
async void StartLapClick(object sender, System.EventArgs e)
{

    if (!inRace)
    {
        inRace = true;
        sw.Start();
        updateTimer();
    }
}

async void updateTimer()
{

    await Task.Run(() =>
    {
        while(inRace)
        {

            string slc = sw.Elapsed.ToString();
            Device.BeginInvokeOnMainThread(() =>
            {
                timerLbl.Text = slc;
            });
            Task.Delay(100).Wait();
        }
    });
}

【问题讨论】:

  • 您的秒表需要什么分辨率?秒还是亚秒?
  • @ctacke 我会以分钟为单位显示时间:seconds.miliseconds

标签: multithreading xamarin.forms async-await task-parallel-library ui-thread


【解决方案1】:

不,您的代码有一些问题(根据Best Practices in Asynchronous Programming):

  • async void 不好 - 这会以即发即弃的方式调用您的方法,您甚至无法从那里得到错误。您应该将它用于像 StartLapClick 这样的事件处理程序,而不是像 updateTimer 这样的真正方法

  • Task.Delay(100).Wait(); - 不要阻塞任务,为此使用await

  • 用一个简单的计时器替换整个while循环,并删除Task.Delay调用

  • updateTimer(); - 你正在以同步方式调用async 方法,这也很糟糕。

【讨论】:

    【解决方案2】:

    您必须从 UI 线程更新 UI。你可以有一个计时器或在后台运行的东西定期踢出事件以被拾取并转发到 UI 线程。即使您这样做了,我也不知道您想要使用并行任务库。这更专注于运行许多任务......并行。

    【讨论】:

    • 我让它与 async 和 await 函数一起工作。这将是最佳做法吗?我已经发布了我开始工作的代码
    • 是的,应该没问题,但一般来说,您应该避免创建返回 void 的异步方法。一方面,如果 UpdateTimer() 内部发生任何异常,则无法捕获它。
    • 非常好的一点,我没有想到函数内部的错误。感谢您的帮助!
    【解决方案3】:

    试试这个:

    Device.StartTimer(TimeSpan.FromSeconds(1.0), () => { 
        // Your code
    };
    

    【讨论】:

    • 谢谢,但我的问题不是启动计时器,而是更新我的 xaml 上的计时器标签,同时仍然能够单击按钮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2014-12-22
    相关资源
    最近更新 更多