すべての 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
MvxMainThreadDispatchingObjecthttps://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 はこれらのクラスによって起動されるまたはイベントのスレッド マーシャリングを行わないことに注意してください。したがって、これらの変更をマーシャリングするのは開発者の責任です。INotifyPropertyChangedINotifyCollectionChanged
理由: ObservableCollectionMS および Mono コード ベースに存在するため、MvvmCross がこれらの既存の実装を変更する簡単な方法はありません。