MvvmCross:在插件中使用InvokeOnMainThread

时间:2013-02-12 10:17:25

标签: c# multithreading xamarin.ios xamarin.android mvvmcross

我正在使用功能扩展Messenger插件,这样就可以在主线程上传递消息,而不是在后台线程上发生的所有事情。

我已经使用BaseSubscription扩展bool,因为我知道需要在主线程上发送此订阅。现在,我需要能够在订阅的实际实现中使用InvokeOnMainThread方法中的TypedInvoke

当我查看引用的MvvmCross程序集时,我看到Cirrious.MvvmCross.ViewModels.MvxMainThreadDispatchingObject包含InvokeOnMainThread方法,所以问题是如何获取该对象以便我可以调用该方法?

1 个答案:

答案 0 :(得分:5)

获取UI线程的最简单方法是继承MvxMainThreadDispatchingObject

如果层次结构不允许您,那么下一个最简单的方法是添加IMvxServiceConsumer标记界面,然后使用GetService<T>扩展方法:

public class MyClass 
   : MyBaseClass
   , IMvxServiceConsumer
{
    // ...

    private bool DoStuff(Action stuff)
    {
        var dispatcherProvider = this.GetService<IMvxMainThreadDispatcherProvider>();
        var dispatcher = dispatcherProvider.Dispatcher;
        if (dispatcher == null) {
           return false;
        }

        return dispatcher.RequestMainThreadAction(action);
    }
 }

如果愿意,也可以将GetService<T>()静态方法作为静态方法调用(如果您不想使用IMvxServiceConsumer)。


注意:

  • 如果您在'Apps'和'Services'/'BackgroundAgents'之间共享代码,则需要非常小心地检查错误情况 - 并不总是有可用的UI线程。

    < / LI>
  • Android特别特别 - 只能通过当前的前台活动访问UI线程 - 目前MvvmCross在IMvxAndroidCurrentTopActivity服务中跟踪此(通过Activity OnStart和OnResume挂钩) - 但不能保证您将始终运行前台活动 - 例如如果你的代码加载了非MvvmCross活动,那么显然MvvmCross将不会知道这些。

  • 你不应该坚持对Dispatcher的引用 - 如果你这样做,那么你可能会将Android Activity的内存超过其自然生命周期

  • 我猜DoStuff也可以加入扩展方法 - 也许我会在v3(https://github.com/slodge/MvvmCross/issues/150)中添加