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



我有以下方法,希望有人能帮助我;它使用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;
}

最新更新