android - Xamarin:如何在 UI 线程上执行长时间运行的操作时让 UI 重绘(不使用 async/await)
问题描述
我(出于某种原因)被迫在我的 xamarin 表单(NetStandard)应用程序的 UI 线程上执行长时间运行的操作。在此操作期间,我想更新 UI 以向用户提供进度反馈。我可以更改 UI,但 UI 不会重绘,因为我无法使用 await/async 将指令指针返回给操作系统。
有什么方法可以在不使用 async/await 的情况下处理 UI 线程上的消息。在旧的 Win32 日子里,我认为 Translate/DispatchMessage 可用于保持消息泵在长时间运行的操作中运行,这与我需要的类似。
背景:我有一个由运行在我的 UI 线程上的 android 操作系统定义和调用的接口。重要的是,我们从该服务返回此长时间运行的操作的结果。因为接口未定义为异步,所以我不能使用 await 让 IP 返回操作系统。如果我这样做了,该函数将立即返回(不获取结果)并继续执行(即,它会失败)。我无法改变这些情况。
// The following class is called directly by the AndroidOS
class CloudHostCardService : HostApduService
{
// The following method is called by the AndroidOS on the UI thread
public override byte[] ProcessCommandApdu(byte[] commandApdu, Bundle extras)
{
ViewModels.MainPageViewModel.SetStatus("Processing Cmd"); // <-- updates UI
return processor.ProcessCommand(commandApdu); // <-- Long running operation
}
}
有没有其他方法可以触发重绘(Win32 中的泵消息)?
解决方案
null
HostApduService 允许您从返回ProcessCommandApdu
,然后使用 SendResponseApdu 来提供ResponseApdu
.
此方法在应用程序的主线程上运行。如果不能立即返回响应 APDU,则返回 null 并稍后使用 sendResponseApdu(byte[]) 方法。
例子:
public class SampleHostApduService : HostApduService
{
public override void OnDeactivated([GeneratedEnum] DeactivationReason reason)
{
}
public override byte[] ProcessCommandApdu(byte[] commandApdu, Bundle extras)
{
// Update your UI via your viewmodel.
// Fire and forget
Task.Run(() => {
this.SendResponseApdu(processor.ProcessCommand(commandApdu));
});
// Return null as we handle this using SendResponseApdu
return null;
}
}
推荐阅读
- c++ - 链接运算符中的临时优化
- c++ - 为什么我的指针数组显示“索引超出有效索引范围”?
- amazon-web-services - 在 terraform 中重用现有模块
- python - 无法让 Python3 识别已安装的模块
- unity3d - 在着色器图中访问二级纹理法线贴图?
- .net-core - .net 核心应用程序是否可以有一些带有客户端凭据流的 API 和其他带有 Open ID 连接的 API
- c# - 从 zip 文件 C# 中检索到的文件名无效
- r - RStudio - 无法安装包“xfun”
- android - 在另一个集合中使用来自一个集合的数据 Firestore Android
- typescript - redux saga 生成器/sagas 上的变量赋值