我有以下方法我希望有人可以帮助我;它使用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中按预期工作; ResetEvent保存我从结果中设置的事件。
然而,在MonoTouch(iOS)中,我什么都没得到,并且重置事件超时(没有任何超时,它永远不会返回)。
通过将locationWatcher作为全局类变量并且不停止它,我可以看到该方法存在后立即返回位置结果。
我想我还可以尝试其他几件事; Thread.Sleep(我觉得很难看)和Locking(但我认为ResetEvent的工作方式几乎相同)。
或者这是一个线程问题和monoTouch的实现?有人建议吗?
提前致谢。
拉纳
答案 0 :(得分:3)
我不熟悉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;
}