帖子已被重写,以更好地解决当前问题。
我有一个按钮x:Name="selectVesselButton"
。单击按钮时,它将尝试建立与服务器的连接,这需要一两秒钟的时间。最初,我希望按钮在从连接中下载并反序列化json文件时显示为灰色。
我的旧代码(在异步之前,尝试更新按钮):
// disabling the button to prevent spam clicking.
string buttonText = selectVesselButton.Text;
selectVesselButton.IsEnabled = false;
selectVesselButton.Text = "loading...";
// retrieve data for speed page.
RetrieveData();
// redirect to next info block if build was successfull.
FocusSpeedblock();
// enabling the button again.
selectVesselButton.Text = buttonText;
selectVesselButton.IsEnabled = true;
此代码的问题在于,按钮的视觉效果直到RetrieveData()完成后才更新,这完全违反了这样做的目的。这是因为用于更新界面的代码以及用于下载和反序列化对象的代码都在同一线程上。
但是,按照Ivan的建议,我进行了Async的下载和反序列化,从而解决了该问题(更像是移动了它)。
这工作得很好,但是我仍然无法自动更新界面。我有一些标签需要根据json文件输出进行更新。标签的值会在背景上更新,但是只有在我与标签互动后(即滚动它们所在的scrollview时)才能在视觉上更新。检查编辑3以获得更多详细信息。
编辑3:
第二个线程完成后,应调用UpdateSpeedLabels()并更新一些标签。但是,它们在后台代码中更新,而没有立即更新接口。仅当我与这些标签互动时,它们才会更新。
答案 0 :(得分:2)
在Xamarin上执行此操作的首选方法是数据绑定。您选择退出后,仍然有可能。
您需要做的是确保长任务不会在UI线程中运行,因为它会阻止它并阻止其更新。您可以通过使用Task.Run(() => { your task code });
来实现。但是,您无法在Task.Run
内部更新用户界面,因为它不在UI线程上运行,并且会导致应用程序崩溃,因此您需要在Device.BeginInvokeOnMainThread(() => { your UI code });
内部使用Task.Run
部分。