Несколько aRFC с WAIT, как синхронизировать доступ к переменной в обратном вызове? - PullRequest
3 голосов
/ 04 мая 2019

Я использую асинхронные RFC-вызовы для параллельной работы в SAP.Здесь вы можете увидеть мой псевдокод.

* class variable
data: gv_counter type i .

....

method start_tasks .

    do 10 times .

        call function 'my_remote_function'
            starting new task task_identifier
            calling task_finish on end of task .

    enddo .

    wait for asynchronous tasks until gv_counter eq 10 .    

endmethod .

.....

method task_finish .

    gv_counter = gv_counter + 1 .

endmethod .

Как видите, я запускаю 10 процессов и жду, пока они все не завершатся.

Мой вопрос касается метода task_finish идоступ к глобальной переменной класса gv_counter.Как я могу гарантировать, что доступ к переменной gv_counter синхронизирован?

Например, в Java я бы сделал что-то подобное:

synchronized {
    gv_counter += 1 ;
}

1 Ответ

5 голосов
/ 04 мая 2019

Вот цитата из документации SAP по теме.

Добавление 2

... {CALLING meth} | {PERFORMING subr}ON END OF TASK

...

Если во время раздела программы регистрируется несколько процедур обратного вызова, они выполняются в неопределенном порядке, когда рабочий процесс изменяется при развертывании.

Для меня это означает, что они будут выполняться один за другим (по порядку), что, однако, не определено.Это будет означать, что ваша переменная всегда будет иметь значение 10.

Вы можете фактически отладить ее, чтобы увидеть, как она обрабатывается последовательно, когда вы ставите точку останова в методе task_finish.Вот мой пример.

REPORT ZZZ.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main,
      task_finish
        IMPORTING
          p_task TYPE clike.
  PRIVATE SECTION.
    CLASS-DATA:
      gv_counter TYPE i.
    CLASS-METHODS:
      start_tasks.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    start_tasks( ).
  ENDMETHOD.

  METHOD start_tasks.
    DATA: l_task TYPE string.
    DO 10 TIMES.
      l_task = sy-index.
      CALL FUNCTION 'Z_ARFC_ECHO'
        STARTING NEW TASK l_task
        CALLING task_finish ON END OF TASK
        EXPORTING
          i_value       = sy-index.

    ENDDO.

    WAIT FOR ASYNCHRONOUS TASKS UNTIL gv_counter = 10.
  ENDMETHOD.

  METHOD task_finish.
    DATA: l_value TYPE sy-index.
    RECEIVE RESULTS FROM FUNCTION 'Z_ARFC_ECHO'
      IMPORTING
        e_echo = l_value.

    WRITE: /, p_task, l_value.

    gv_counter = gv_counter + 1.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

Мой RFC выглядит следующим образом

FUNCTION Z_ARFC_ECHO.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(I_VALUE) TYPE  SY-INDEX
*"  EXPORTING
*"     VALUE(E_ECHO) TYPE  SY-INDEX
*"----------------------------------------------------------------------

e_echo = i_value.

ENDFUNCTION.

Что также интересно (и также упомянуто в документации), операторы вывода списка типа WRITE не являютсяобрабатывается в таком обработчике, поэтому вы не видите ничего распечатываемого в конце выполнения вышеупомянутого отчета.

...