我正在使用 Xamarin Mobile Blazor Bindings 开发 Android/iOS 位置跟踪器应用程序。我不认为我特别使用 Xamarin Mobile Blazor 绑定这一事实是相关的,但我提到它是为了完整性。
该应用每 15 秒轮询一次移动设备的当前 GPS 位置,并在收到新位置时调用自定义事件,通知任何已注册该事件的 Blazor UI 组件。
所有 GPS 逻辑和事件处理都在一个简单的(非 UI)单例类中完成,如下所示:
public class MyLocationManager
{
public event EventHandler<LocationUpdatedEventArgs> OnLocationUpdateReceived;
private Timer _timer;
public void StartLocationTracking()
{
if (DeviceInfo.Platform == DevicePlatform.Android)
{
// On Android, Location can be polled using a timer
_timer = new Timer(
async stateInfo =>
{
var newLocationCoordinates = await _addCurrentLocationPoint();
var eventArgs = new LocationUpdatedEventArgs
{
Latitude = newLocationCoordinates.Latitude,
Longitude = newLocationCoordinates.Longitude
};
// **** The following line generates an Exception ****
OnLocationUpdateReceived?.Invoke(this, eventArgs)
},
new AutoResetEvent(false),
15000 /* Wait 15 seconds before initial call */,
15000 /* Then repeat every 15 seconds */
);
}
}
}
不幸的是,当定时器触发时,以下代码会产生异常:
OnLocationUpdateReceived?.Invoke(this, eventArgs)
例外是:
System.InvalidOperationException: '当前线程与 Dispatcher 无关。触发渲染或组件状态时,使用 InvokeAsync() 将执行切换到 Dispatcher。
现在,我明白异常在说什么,当前正在运行的非 UI 线程不能用于调用事件,所以我需要以某种方式使用 Dispatcher 线程。
但是,提到的“InvokeAsync()”方法似乎只存在于 UI 组件的基类中,而“MyLocationManager”类不存在。
任何人都可以就我如何从诸如此类的非 UI 类中实现相同的目标提供任何建议吗?
感激地收到任何建议。
您是否尝试过通过组件上的状态处理程序使用 InvokeAsync?您可以使用这种方法,而不是在管理器上使用它:如何修复“当前线程与渲染器的同步上下文无关”?
实际上,您注册更改处理程序事件并在组件端执行 InvokeAsync:
private async void OnMyChangeHandler(object sender, EventArgs e)
{
// InvokeAsync is inherited, it syncs the call back to the render thread
await InvokeAsync(() => {
DoStuff();
StateHasChanged());
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句