Ala*_*an2 8 c# xamarin xamarin.forms
我有工作,但是当我调试在我的iPhone一段时间后它挂了电话,我可以恢复的唯一方法是在一侧的按钮,主页按钮的硬复位的应用程序.
首先,可能是因为我的应用程序有内存泄漏?
这是应用程序的代码.特别是,我正在研究这种BeginInvokeOnMainThread方法.有人可以告诉我他们是否可以看到它的实施方式是否存在任何问题?另外,这是什么目的.ContinueWith((arg).
namespace Japanese
{
public partial class PhrasesFrame : Frame
{
CancellationTokenSource cts = new CancellationTokenSource();
public PhrasesFrame(PhrasesPage phrasesPage)
{
InitializeComponent();
this.phrasesPage = phrasesPage;
AS.phrasesFrame = this;
Device.BeginInvokeOnMainThread(() => ShowCards(cts.Token).ContinueWith((arg) => { }));
}
public void Disappearing()
{
cts.Cancel();
}
public async Task ShowCards(CancellationToken ct)
{
AS.cardCountForSelectedCategories = App.DB.GetCardCountForSelectedCategories();
while (!ct.IsCancellationRequested)
{
await Task.Delay(500);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
首先,让我们解决您的问题.ContinueWith((arg) => { })).ContinueWith在原始文件Task完成后告诉更多代码执行.在我们的例子中,里面的代码ContinueWith将运行一次Device.BeginInvokeOnMainThread(() => ShowCards(cts.Token).
在这种情况下,里面没有代码ContinueWith,所以我们可以删除它.
是的,我可以看到此代码有可能冻结UI.
BeginInvokeOnMainThread将队列化Action以在主线程(也称为UI线程)上运行.主线程一直在监听用户输入(点击屏幕上的按钮,捏合缩放等),如果此线程忙于执行长时间运行的任务,它将无法响应用户的输入直到完成; 因此你的应用程序将显示为冻结
代码await Task.Delay(500);由主线程调用.因此,我们告诉主线程冻结自己500毫秒,并无限循环.
一种解决方案是将这些代码包装Task.Run在后台线程中并释放主线程以监听/响应用户输入.
Task.Run(async () =>
{
while (!ct.IsCancellationRequested)
{
await Task.Delay(500);
}
}
Run Code Online (Sandbox Code Playgroud)
仅BeginInvokeOnMainThread在需要更新UI时使用.99%的代码可以在后台线程上运行而没有任何问题.然而,1%是更新UI的代码; 任何更新UI的代码都必须在主线程上运行.
如果执行的任务花费的时间超过了屏幕的刷新率,请在后台线程上执行.例如,如果屏幕的刷新率为60Hz,则每16.7ms更新60次/秒.因此,如果我们有一个需要20ms执行的代码块,我们需要在后台线程上执行它,以确保我们不冻结应用程序并删除任何帧.
await Task.Run(() => AS.cardCountForSelectedCategories = App.DB.GetCardCountForSelectedCategories());Run Code Online (Sandbox Code Playgroud)