MVVMCross中视图模型的UI线程问题

MVVMCross中视图模型的UI线程问题,mvvm,mvvmcross,Mvvm,Mvvmcross,我正在将MVVMCross与我的跨平台Windows Phone和Android应用程序一起使用。在核心项目的主视图模型中,我正在使用TPL做一些后台工作,我想确保在回调中,当我更改视图模型的属性(这将触发UI更改)时,代码在UI线程上运行,我如何实现这一点 对于代码,下面是它的风格 private MvxGeoLocation _currentLocation; private Task<MvxGeoLocation> GetCurrentLocation()

我正在将MVVMCross与我的跨平台Windows Phone和Android应用程序一起使用。在核心项目的主视图模型中,我正在使用TPL做一些后台工作,我想确保在回调中,当我更改视图模型的属性(这将触发UI更改)时,代码在UI线程上运行,我如何实现这一点

对于代码,下面是它的风格

    private MvxGeoLocation _currentLocation;
    private Task<MvxGeoLocation> GetCurrentLocation()
    {
        return Task.Factory.StartNew(() =>
            {
                while (_currentLocation == null && !LocationRetrievalFailed)
                {
                }
                return _currentLocation;
            });
    }

    var location = await GetCurrentLocation();
    if (LocationRetrievalFailed)
    {
        if (location == null)
        {
            ReverseGeocodingRequestFailed = true;
            return;
        }
        // Show toast saying that we are using the last known location
    }
    Address = await GooglePlaceApiClient.ReverseGeocoding(location);
私有MvxGeoLocation\u currentLocation;
私有任务GetCurrentLocation()
{
返回Task.Factory.StartNew(()=>
{
而(_currentLocation==null&&!LocationRetrievalFailed)
{
}
返回当前位置;
});
}
var location=等待GetCurrentLocation();
如果(LocationRetrievalFailed)
{
if(位置==null)
{
ReverseGeocodingRequestFailed=true;
返回;
}
//显示吐司,说明我们正在使用最后一个已知位置
}
地址=等待GooglePlaceApiClient.ReverseGeocode(位置);

您是否尝试了
IMvxMainThreadDispatcher

var dispatcher = Mvx.Resolve<IMvxMainThreadDispatcher>();
dispatcher.RequestMainThreadAction(()=> { .... });
var dispatcher=Mvx.Resolve();
dispatcher.RequestMainThreadAction(()=>{..});
请参阅有关实施的更多信息:

通常我认为你不需要这个

由于从主线程开始异步处理,异步操作应该返回到主线程


你能举一个你正在做的异步代码的例子吗?

方法
RequestMainThreadAction
现在已经过时了。今天你要做什么

var dispatcher = Mvx.Resolve<IMvxMainThreadAsyncDispatcher>();
await dispatcher.ExecuteOnMainThreadAsync(()=> { .... });
var dispatcher=Mvx.Resolve();
等待dispatcher.ExecuteOnMainThreadAsync(()=>{….});

2020年8月24日更新: 正如@claudio redi所提到的,需要使用
ExecuteOnMainThreadAsync
。但是
Mvx.Resolve
现在已经过时了。因此,最新的片段是:

var mainThreadAsyncDispatcher = Mvx.IoCProvider.Resolve<IMvxMainThreadAsyncDispatcher>();
await mainThreadAsyncDispatcher.ExecuteOnMainThreadAsync( async ()=> { await SomeAsyncTask() });
var mainthreadsynchdispatcher=Mvx.IoCProvider.Resolve();
await mainThreadAsyncDispatcher.ExecuteOnMainThreadAsync(async()=>{await SomeAsyncTask()});

这里还有很多问题,就像我添加了一些代码示例一样。另外,我想知道在主UI线程之外的线程中修改ViewModel属性是否安全?当您说“既然从主线程开始异步处理,异步操作应该返回到主线程。”时,您是指C#5.0的异步/等待还是仅任务?或者两者都有?我想知道我是否将ContinueWith回调附加到任务上,它是在调用方线程上还是在任务线程上?不要介意我前面的问题,我将通过编写一个返回到调用方线程的testContinueWith来尝试解决这个问题。再次呼叫等待也是一样的。这是一本非常好的读物: