需要帮助获取位置触摸作为异步任务(在wp中工作)

时间:2014-02-21 22:46:17

标签: mvvmcross

我有以下方法我希望有人可以帮助我;它使用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的实现?有人建议吗?

提前致谢。

拉​​纳

1 个答案:

答案 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;
}