Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在UI线程上使用计时器更新标签文本,而不阻塞UI_C#_Xamarin - Fatal编程技术网

C# 在UI线程上使用计时器更新标签文本,而不阻塞UI

C# 在UI线程上使用计时器更新标签文本,而不阻塞UI,c#,xamarin,C#,Xamarin,我有一个标签,我想每10秒更新一次。不幸的是,正如现在一样,事件阻塞了UI,这意味着我无法与应用程序交互 我试图创建一个新线程来运行任务,但应用程序告诉我,我无法从非主线程进行特定于UI的更改 代码如下: Public partial class FrontPage : ContentPage { public FrontPage() { updateLabel(); } updateLabel() { while(true

我有一个标签,我想每10秒更新一次。不幸的是,正如现在一样,事件阻塞了UI,这意味着我无法与应用程序交互

我试图创建一个新线程来运行任务,但应用程序告诉我,我无法从非主线程进行特定于UI的更改

代码如下:

Public partial class FrontPage : ContentPage
{
    public FrontPage()
    {
        updateLabel();
    }
    updateLabel()
    {
        while(true)
        {
            test.Text = i;
            Thread.Sleep(10000);
            i++;
        }
    }
}
由于我需要异步运行此操作以避免阻塞UI,因此我怀疑该解决方案涉及wait/async操作符。不幸的是,在这种情况下,我不确定如何实现它。

请改用,并使用强制在UI线程上执行UI更新

System.Timers.Timer t = new System.Timers.Timer(10000);
t.Elapsed += OnTimedEvent;
t.AutoReset = true;
t.Enabled = true;

private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
  Device.BeginInvokeOnMainThread( () => {
    test.Text = i;
    i++;
  });
}
了解如何在UI线程上运行方法,并仍然与UI交互。因此,恐怕在这种情况下不可能使用计时器

您可以使用一个线程(通过
Task.Run
),然后使用
Device.InvokeOnMainThreadAsync
Device.BeginInvokeOnMainThread
在该“后台”线程内执行UI更新:


注意:也不要使用
Thread.Sleep
,因为这将挂起整个线程,包括它的消息泵(当它是UI/主线程时,这是一件非常糟糕的事情)。

这只是我编的一个示例,以了解如何在UI线程上运行方法,并且仍然与UI交互。因此,在这种情况下,恐怕不可能使用计时器。“使用BeginInvokeOnMainThread强制在UI线程上执行UI更新”如果您不打算实际利用它,那么使用
async
Wait
有什么意义?最好只删除
任务.Run()
等待设备.InvokeOnMainThreadAsync()
等待任务延迟(10000)
将把线程返回给调用方,当延迟到期时,该方法将继续在主线程中运行,正如所需。您不需要所有其他的东西。@PeterDuniho强调,在移动环境中,尽可能多地从主/UI线程中删除处理。w/多核|大|小核调度,消耗主/用户界面线程周期,生产“laggie”应用程序,UI yank,更高的电池使用率,等等…@PeterDuniho,他不是在寻找“计时器”解决方案。。。在另一个答案中看到他的评论。呃,你上面的代码并不能解决你描述的任何问题。事实上,它使这些问题变得更糟,因为它在线程和其他对象之间添加了新的转换。OP想要一个“非计时器”解决方案的事实并不能原谅你的建议所带来的额外的无用线程切换层。它显示了你的答案应该是什么(考虑到重复问题是多么容易找到,暂时忽略你的答案本来就不应该是的)。
Task.Run(async() =>
{
    while (true)
    {
        await Device.InvokeOnMainThreadAsync(() =>
        {
            test.Text = i;
        });
        await Task.Delay(10000);
        i++;
    }
});