创建一个侦听器以停止方法,直到自定义回调完成

时间:2019-05-05 19:37:06

标签: c# asynchronous xamarin.android async-await delegates

我想停止一个方法,直到自定义委托在Xamarin.Android中提供从一种方法到另一种方法的侦听器的回调为止,但是我在理解这种侦听器的实现时遇到很多麻烦。

我只是试图了解如何做到这一点,但是我对委托的构造和调用方式还是很困惑。

假设我要停止此MainActivity方法

    public async override void OnWindowFocusChanged(bool hasFocus)
    {
           base.OnWindowFocusChanged(hasFocus);

           //how can I create a listener to stop this method until callback from OnPause?
           //await a delegate task?

    }

并等待Fragment中的另一个方法:

    public override void OnResume()
    {
         base.OnResume();

         //I'd like to implement a delegate here to notify the OnWindowFocusChanged that OnResume method has been invoked
         //what would be the construction of such?
    }

我该怎么办?

根据我的研究,我认为我需要创建一个委托任务,然后等待它在OnWindowFocusChanged中返回。但是,我对这种解决方案的实施感到困惑。如果任何人都可以提供一个非常基本的伪代码示例,那将对我有很大帮助。

编辑:我将OnPause更改为OnResume,因为这对于理解我要执行的操作更有用。以下答案引用了OnPause,但无论如何,这两种方法极为相似。

这是一个几乎做我想做的事的例子;除了在调用OnResume时不启动我的方法外,OnWindowFocusChanged会停止10000ms。因此,基本上,我想用自定义委托(类似于事件)替换计时器,该任务在调用Fragment.OnResume时返回。

    public async override void OnWindowFocusChanged(bool hasFocus)
    {
         base.OnWindowFocusChanged(hasFocus);

         //we won't pass this line for 10000ms; how to replace with Task return?
         await WaitHere();
    }


    async Task WaitHere()
    {
        System.Threading.Thread.Sleep(10000);
    }

1 个答案:

答案 0 :(得分:0)

您可以尝试使用Task.Run这样的方法:

await Task.Run(() => OnPause());

这基本上将创建一个新线程或使用您正在使用的线程,并在此行之后安排所有内容作为继续。所以是的,该方法将停止,但是除非您处于某个GUI线程上(不阻塞)或运行一些IO任务,否则这是不必要的。

我不太了解您要实现的目标,但是您可能会尝试创建新的OnPauseAsync方法,该方法将在任务完成时返回Task以从该方法中获取一些结果。这样,您将获得不会阻塞的顺序式机制。

如果您想真正地并行运行这些方法,但停止执行OnWindowFocusChanged unitl,则在OnPause中会发生某些事情,您应该使用裸线程和某些同步原语,例如Mutex或Barrier。然后,您将可以使“主”线程等待,直到发生某些事情为止(但是它将阻止!当心)。关于这些小伙子,您可以在这里了解更多信息:LINK_WITH_FOCUS_ON_BARRIER

我不确定自己的意图是否正确,但希望最终能有所帮助。

要查看:

  • 如果您只想等待OnPause完成并且它仅占用CPU大量资源,并且您不在UI线程上-请勿执行任何操作,因为使用线程等无益。
  • 如果onPause可以做一些IO繁重的事情,您可以使用:

    • 任务-可能在一个线程上执行且不会阻塞,在OnWindowFocusChanged完全完成后,控制权返回到onPause
    • 线程-如果要运行一些并行(保证有两个线程)计算,并等待onPause向其调用者发出可能会继续执行的信号,请使用例如Barrier-但要注意从程序员的角度来看,这是最复杂的解决方案,如果您使用的是UI线程,则会阻止它。