提问人:lomstfer 提问时间:7/22/2023 最后编辑:ToolmakerStevelomstfer 更新时间:7/28/2023 访问量:85
为什么此计数器在 Windows 上正确递增,但在 Android 上却不然?
Why does this counter increment correctly on Windows, but not on Android?
问:
我从 Maui 模板项目开始,您可以在其中单击一个按钮来增加存储在 MainPage 类中的数字。
我删除了除 MainPage.xaml 中的标签之外的所有元素。我将此标签命名为 SpeedLabel,以便可以从 MainPage 类更改它。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Metero.MainPage">
<Label
x:Name="SpeedLabel"
Text="0"
SemanticProperties.HeadingLevel="Level1"
SemanticProperties.Description="Welcome to dot net Multi platform App U I"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center" />
</ContentPage>
现在,在MainPage C#类(MainPage.xaml.cs)中,我将类更改为:
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
SpeedLabelUpdate();
}
private async void SpeedLabelUpdate()
{
while (true) {
count += 1;
SpeedLabel.Text = count.ToString();
await Task.Delay(100);
}
}
}
我希望这将生成一个应用程序,其数字在屏幕中央不断增加。它在 Windows 上按预期工作,但在 Android 上则不然。
在 Android 上,该数字按预期上升到 9,但随后它被重置为 1,现在更新之间的延迟是 1000 毫秒而不是 100 毫秒。如果我继续运行,它会在达到 9 时再次重置,现在延迟约为 10000 毫秒。
答:
1赞
Peter Wessberg
7/22/2023
#1
这就是线程安全的方式。尝试看看这是否更适合您。
Dispatcher.StartTimer(TimeSpan.FromMilliseconds(100), () =>
{
count += 1;
SpeedLabel.Text = count.ToString();
return true;
});
评论
0赞
lomstfer
7/22/2023
谢谢你,但它不起作用!我还有同样的问题!
0赞
Peter Wessberg
7/22/2023
这很奇怪。我已经尝试了您的代码,这两者都对我有用。也许是您的手机或其他原因使 Android 认为代码没有响应或操作系统以某种方式干扰。
0赞
Peter Wessberg
7/23/2023
在更新原始代码中的标签时,您能否看看这是否适合您:Dispatcher.Dispatch(() => SpeedLabel.Text = count。ToString());
0赞
lomstfer
7/23/2023
如果你的意思是这样的:while (true) { count += 1;Dispatcher.Dispatch(() => SpeedLabel.Text = 计数。ToString());等待 Task.Delay(100);} 那么这是同样的问题。
0赞
Peter Wessberg
7/23/2023
很抱歉听到这个消息。我认为这不是编码问题,而是其他问题。
1赞
lomstfer
7/23/2023
#2
private async void SpeedLabelUpdate()
{
while (true)
{
count += 1;
TempLabel.Dispatcher.Dispatch(() =>
{
TempLabel.Text = count.ToString();
});
await Task.Delay(100);
}
}
评论
0赞
lomstfer
7/23/2023
这就是我最终所做的,也是解决问题的原因。
1赞
ToolmakerSteve
7/23/2023
啊,我以为这和你在评论中说的代码相同,不起作用。在这里,您将 Task.Delay 移到了 Dispatch 之外。好;[如果 Task.Delay 在 Dispatch 中,那么循环将尝试运行得非常非常快,因为它没有延迟。Dispatch 内部内容单独运行。该注释中的代码会“堆积”许多 Dispatch,从而导致速度变慢和其他问题。最终会使应用程序崩溃。
0赞
ToolmakerSteve
7/23/2023
#3
这行代码:
SpeedLabelUpdate();
应在 Visual Studio 中显示警告。右?不要忽略该警告。
警告建议添加 .但你不能。这是一个暗示,你正在做的事情是不可靠的。await
通过创建一个上下文来修复它,您可以从中:async
await
public MainPage()
{
InitializeComponent();
// Code inside here runs AFTER "MainPage()" method returns.
// Use "Dispatcher.Dispatch", because SpeedLabelUpdate touches UI.
Dispatcher.Dispatch( async() =>
{
await SpeedLabelUpdate();
}
}
评论
async