Parellel任务库与UI线程Xamarin.Forms不断更新UI时

时间:2017-05-01 07:33:31

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

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

我试图使用PT Lib,但是我无法让它更新我的标签,这让我觉得我应该使用Native Threading,但是我担心我是否能够更新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();
        }
    });
}

3 个答案:

答案 0 :(得分:1)

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

  • async void很糟糕 - 这会让您的方法以一种“一劳永逸”的方式称呼,您甚至无法从中获取错误。您应该将用于StartLapClick等事件处理程序,而不是像updateTimer

    这样的实际方法
  • Task.Delay(100).Wait(); - 请勿阻止任务,请使用await

  • 使用简单的计时器替换整个while循环,然后移除Task.Delay调用

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

试试这个:

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