我有以下方法,希望有人能帮助我;它使用MvvmCross IMvxLocationWatcher。基本上,这个想法是从封装观察器的方法中获得MvxGeoLocation结果。
protected internal static async Task<MvxGeoLocation> GetCurrentLocationAsync()
{
const int timeoutInMs = 5000;
return await Task.Factory.StartNew(() =>
{
MvxGeoLocation result = null;
// wait event
var manualResetEvent = new ManualResetEvent(false);
var locationWatcher = Mvx.Resolve<IMvxLocationWatcher>();
locationWatcher.Start(new MvxLocationOptions {Accuracy = MvxLocationAccuracy.Coarse},
// success
location =>
{
result = location;
manualResetEvent.Set();
},
// fail
error =>
{
result = null;
manualResetEvent.Set();
});
// all done
manualResetEvent.WaitOne(timeoutInMs);
locationWatcher.Stop();
return result;
});
}
此代码在 WindowsPhone 中按预期工作;重置事件保存我从结果中设置的事件。
但是,在MonoTouch(iOS)中,我什么也得不到,并且重置事件超时(没有任何超时,它永远不会返回)。
通过将 locationWatcher 作为全局类变量并且不停止它,我可以看到只要此方法存在,位置结果就会返回。
我想还有其他几件事我可以尝试;Thread.Sleep(我觉得这很丑陋)和锁定(但我认为ResetEvent几乎以同样的方式工作)。
或者这是线程问题和单点触控的实现?有人建议吗?
提前谢谢。
蛙
我不熟悉IMvxLocationWatcher
实现的线程模型。但是您可能会在 UI 线程上获得更好的结果(并且肯定有更好的性能):
protected internal static Task<MvxGeoLocation> GetCurrentLocationAsync()
{
var tcs = new TaskCompletionSource<MvxGeoLocation>();
const int timeoutInMs = 5000;
var locationWatcher = Mvx.Resolve<IMvxLocationWatcher>();
locationWatcher.Start(new MvxLocationOptions {Accuracy = MvxLocationAccuracy.Coarse},
// success
location => tcs.TrySetResult(location),
// fail
error => tcs.TrySetException(error));
return tcs.Task;
}