Создайте прослушиватель для остановки метода до завершения пользовательского обратного вызова - PullRequest
0 голосов
/ 05 мая 2019

Я бы хотел остановить метод до тех пор, пока пользовательский делегат не предоставит обратный вызов от одного метода слушателю другого в 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?

    }

и ожидайте другого метода внутри фрагмента:

    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 останавливается на 10000 мс.Поэтому я хотел бы заменить таймер пользовательской задачей делегата (аналогично событию), которая возвращается при вызове 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 голосов
/ 05 мая 2019

Вы можете попробовать Task.Run метод как:

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

В основном это создаст новую тему или использует ту, в которой вы находитесь, и запланируйте все после этой строки как продолжение. Так что да, метод вроде бы остановился, но если вы не находитесь в каком-либо потоке графического интерфейса (чтобы не блокировать) или не выполняете какую-либо задачу ввода-вывода, это не нужно.

Я не совсем понимаю, чего вы пытаетесь достичь, но вы можете попытаться создать новый метод OnPauseAsync, который будет возвращать Task, чтобы получить некоторый результат от метода после его завершения. Таким образом, вы получите последовательный механизм, который не блокирует.

Если вы хотите действительно запустить эти методы параллельно, но прекратить выполнение OnWindowFocusChanged unitl, что-то происходит в OnPause, вам следует использовать открытые потоки и некоторые примитивы синхронизации, такие как Mutex или Barrier. Тогда вы сможете заставить «основной» поток ждать, пока что-то произойдет (но он заблокирует! Остерегайтесь). Подробнее об этих парнях вы можете прочитать здесь: LINK_WITH_FOCUS_ON_BARRIER

Я не совсем уверен, что правильно понял ваши намерения, но, надеюсь, это как-то поможет в конце.

Отзыв:

  • если вы просто хотите дождаться завершения OnPause, и он выполняет только тяжелые процессы процессора, а вы не в потоке пользовательского интерфейса - ничего не делайте, поскольку нет никакой пользы от использования потоков и т. Д.
  • если onPause выполняет некоторые тяжелые операции ввода-вывода, которые вы можете использовать:

    • Задачи - потенциально выполняются в одном потоке и не блокируются, управление возвращается в OnWindowFocusChanged ПОСЛЕ onPause Полное завершение.
    • Потоки - если вы хотите выполнить несколько параллельных (с гарантией двух потоков) вычислений и подождать, пока onPause не сообщит в НЕКОТОРЫЙ ТОЧКЕ выполнения своему вызывающему абоненту, что он может продолжаться, вы можете использовать, например, Barrier - но будьте осторожны, так как это самое сложное решение с точки зрения программистов, и оно блокируется, если вы находитесь в потоке пользовательского интерфейса.
...