すべての MvvmCross プラットフォームでは、UI アクションが UI スレッド/アパートメントにマーシャリングされる必要がありますが、各プラットフォームではこれが異なります....
これを回避するために、MvvmCross はこれを行うためのクロスプラットフォームの方法を提供します -IMvxViewDispatcherProvider
注入されたオブジェクトを使用します。
たとえば、WindowsPhone では、IMvxViewDispatcherProvider
最終的MvxMainThreadDispatcher
にhttps://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxMainThreadDispatcher.csで提供されます。
InvokeOnMainThread
これは次を使用して実装します。
private bool InvokeOrBeginInvoke(Action action)
{
if (_uiDispatcher.CheckAccess())
action();
else
_uiDispatcher.BeginInvoke(action);
return true;
}
ViewModel のコードの場合:
- あなたの
ViewModel
継承元MvxViewModel
- から
MvxViewModel
継承しますMvxApplicationObject
- から
MvxApplicationObject
継承しますMvxNotifyPropertyChanged
MvxNotifyPropertyChanged
オブジェクトはMvxMainThreadDispatchingObject
MvxMainThreadDispatchingObject
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxMainThreadDispatchingObject.csです。
public abstract class MvxMainThreadDispatchingObject
: IMvxServiceConsumer<IMvxViewDispatcherProvider>
{
protected IMvxViewDispatcher ViewDispatcher
{
get { return this.GetService().Dispatcher; }
}
protected void InvokeOnMainThread(Action action)
{
if (ViewDispatcher != null)
ViewDispatcher.RequestMainThreadAction(action);
}
}
だから...あなたのViewModelはただ呼び出すことができますInvokeOnMainThread(() => DoStuff());
もう 1 つの注意点は、MvvmCross が、メソッドを介してMvxViewModel
(または実際には任意のMvxNotifyPropertyChanged
オブジェクトで)通知されるプロパティ更新の UI スレッド変換を自動的に行うことです。以下を参照してください。RaisePropertyChanged()
protected void RaisePropertyChanged(string whichProperty)
{
// check for subscription before going multithreaded
if (PropertyChanged == null)
return;
InvokeOnMainThread(
() =>
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(whichProperty));
});
}
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNotifyPropertyChanged.csで
この呼び出しの自動マーシャリングはRaisePropertyChanged()
、ほとんどの状況でうまく機能しますが、バックグラウンド スレッドから多くの変更されたプロパティを発生させると、少し非効率になる可能性があります。多くのスレッド コンテキストの切り替えが発生する可能性があります。ほとんどのコードで意識する必要はありませんが、問題がある場合は、次のようにコードを変更すると役立ちます。
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
に:
InvokeOnMainThread(() => {
MyProperty1 = newValue1;
MyProperty2 = newValue2;
// ...
MyProperty10 = newValue10;
});
を使用する場合ObservableCollection
、MvvmCross はこれらのクラスによって起動されるまたはイベントのスレッド マーシャリングを行わないことに注意してください。したがって、これらの変更をマーシャリングするのは開発者の責任です。INotifyPropertyChanged
INotifyCollectionChanged
理由: ObservableCollection
MS および Mono コード ベースに存在するため、MvvmCross がこれらの既存の実装を変更する簡単な方法はありません。