简体   繁体   中英

How to use json.net asynchronously in WinRT's app ViewModel?

I have MVVM(Prism) Windows Store app and I don't understand how to do asynchronous serialization/deserialization using Json.NET library(Version 6.0.4) in ViewModel layer.

I have method which is bound to GridView's ItemClick event:

public async void GridViewClick(object sender, ItemClickEventArgs parameter)
    {
        if (App.IsInternet())
        {
            if (parameter != null)
                _navigationService.Navigate("AnimeDetails",
                    await Task.Run(() => JsonConvert.SerializeObject(parameter.ClickedItem)));
        }
        else
        {
            new MessageDialog(ResourceController.GetTranslation("MainPage_FeatureUnavaliableOffline")).ShowAsync();
        }
    }

This method throws me following Exception:

The application called an interface that was marshalled for a different thread. (Исключение из HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

I tried to use Dispatcher, but it didn't help me(similar wrong thread exception).

        public async void GridViewClick(object sender, ItemClickEventArgs parameter)
    {
        if (App.IsInternet())
        {
            var serializedItem = string.Empty;
            await
                Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    async () =>
                        await Task.Run(() => serializedItem = JsonConvert.SerializeObject(parameter.ClickedItem)));
            if (parameter != null)
                _navigationService.Navigate("AnimeDetails", serializedItem);
        }
        else
        {
            new MessageDialog(ResourceController.GetTranslation("MainPage_FeatureUnavaliableOffline")).ShowAsync();
        }
    }

Could anybody please explain me, how to do serialization/deserialization correctly?

Usually, serialization is fast enough you can just do it directly without messing with background threads at all:

if (parameter != null)
  _navigationService.Navigate("AnimeDetails",
      JsonConvert.SerializeObject(parameter.ClickedItem));

However, if your objects are really huge and you're sure you want to use a background thread, then you just have to do any UI access (ie, ItemClickEventArgs.ClickedItem ) on the UI thread and serialization on the background thread:

if (parameter != null)
{
  var item = parameter.ClickedItem;
  _navigationService.Navigate("AnimeDetails",
      await Task.Run(() => JsonConvert.SerializeObject(item)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM