Georg Kohler Ответов: 0

Много вызовов не работает


Я должен признаться, что не очень понимаю этот асинхронный вызов
Ниже код, кажется, "терпит неудачу для меня или лучше не ведет себя так, как я ожидал бы
Я звоню
WAIT_MOVING()
из моего основного потока и хотел бы ждать в цикле запуска новой задачи, чтобы ждать
IsMoving
изменить состояние
Основная идея заключается в том, чтобы основной поток оставался отзывчивым, но ждал завершения задачи ...
Кажется, этого не происходит
- Задача запускается и выполняет свою работу, но основной поток продолжает идти - как и не ждет завершения задачи.
Опять же главная задача состоит в том, чтобы держать основной поток отзывчивым, пока мы ждем
IsMoving
флаг должен быть установлен.
Есть идеи, почему это не работает так, как ожидалось ?




Friend Async Sub WAIT_MOVING()
       Dim AbortWait As Boolean = Await Task.Run(Function()
                                                     Return WaitFor_Moving()
                                                 End Function)
       If AbortWait Then
           doSomething
       End If
   End Sub

   Friend Function WaitFor_Moving() As Boolean

       While Not IsMoving
           If MC_Alive = False then
               Return True
          endif
       End While

       Return False
   End Function


Что я уже пробовал:

Многочисленные вариации асинхронных вызовов, казалось, не дали мне "ожидаемого "результата

Richard Deeming

Что "основная нить продолжает идти" значит?

Код, который вызывает WAIT_MOVING не имеет никакого способа дождаться завершения метода. Дело в том, что VB.NET эквивалент Ан async void метод, который следует избегать везде, где это возможно[^].

Кроме того, как это происходит? IsMoving свойство изменено? Возможно, есть более эффективный способ дождаться его изменения, чем тестировать его в узком цикле.

Georg Kohler

Ismoving модифицируется другой нитью, которая обрабатывает перемещение оси.
После командования осью возникает короткая задержка, прежде чем они действительно запускаются, обычно несколько МС, но если мы никогда не начинаем движение, то основной поток-это единственное, что может остановить процесс (нажав кнопку stop на графическом интерфейсе и отменив цикл ожидания)

Нам действительно нравится улавливать изменение флага isMoving как можно быстрее, потому что это движение может быть очень коротким (10 мс или около того)

Асинхронный вызов казался правильным решением (если он работал)

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

Any ideas on how to accomplish this without blocking the main thread 
I'm open to any ideas

Richard Deeming

Предполагая, что у вас есть контроль над другим потоком, вы можете использовать TaskCompletionSource<bool>[^] чтобы создать задачу, которая завершается, когда свойство становится True.

Когда вы говорите "следующий метод", вы имеете в виду doSomething из вашего вопроса или следующего метода WAIT_MOVING?

Georg Kohler

Еще один метод следующий за Wait_move

Проблема заключается в сроках, так как ожидание может быть очень коротким (5 мс-это то, что я вижу сейчас)
Я мог бы использовать простой цикл с задержкой в основном потоке, но это делает его невосприимчивым к коротким задержкам (используя sleep)
Я надеялся на более чистое решение :-)

"doSomething" - это просто для меня, чтобы отменить переезд, если что-то пойдет не так

Richard Deeming

Как я уже сказал, WAIT_MOVING ничего не возвращает, поэтому вызывающий код не может узнать, когда он закончен.

Если вы хотите подождать, пока он закончит, вам нужно будет изменить его, чтобы он был Function вот и вернулся а Task:

Friend Async Function WAIT_MOVING() As Task
    Dim AbortWait As Boolean = Await Task.Run(Function()
        Return WaitFor_Moving()
    End Function)
    
    If AbortWait Then
       doSomething
    End If
End Function
Затем вызывающий код будет использовать Await дождаться завершения вызова, прежде чем продолжить:
Await WAIT_MOVING()
doSomethingElse

Georg Kohler

Разве это не то, что у меня уже было ? .. Должно быть, я что-то пропустил.
-Я попробую и дам тебе знать

Georg Kohler

Я действительно изменил его, как было предложено, и он начал действовать так, как можно было бы ожидать ... в конце концов я изменил вызывающий поток, так что теперь я могу ждать непосредственно флага, вообще не используя асинхронные вызовы - я чувствую себя намного лучше в этом подходе - & но я действительно кое-чему научился :-)
Спасибо!

0 Ответов