Таймер Java не запускается при использовании вызова JNA для Win32 WaitForSingleObject () - PullRequest
2 голосов
/ 22 декабря 2011

Я пытаюсь завершить вызов JNA на WaitForSignleObject() с помощью Timer, который прерывает текущий поток:

final Thread thread = Thread.currentThread();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
  public void run() {
    thread.interrupt();
  }
}, 3000);

try {               
  Kernel32.INSTANCE.WaitForSingleObject(processInfo.hProcess, Kernel32.INFINITE);
  ...
} catch (InterruptedException e) {
}

Проблема в том, что TimerTask.run() не вызывается через 3 секунды, как ожидалось, он вызывается только после выхода WaitForSingleObject(). Что я делаю не так?

Спасибо!

Ответы [ 4 ]

2 голосов
/ 23 декабря 2011

Механизм прерывания потока является специфической для Java функцией, поэтому неудивительно, что нативный код этого не учитывает.

Если вам нужен только тайм-аут, вы можете использовать второй аргумент WaitForSingleObject(). Если вам нужна более сложная логика, вы можете создать событие , чтобы уведомить ожидающий поток о прерывании, и использовать WaitForMultipleObjects() для этого события и свой hProcess.

1 голос
/ 23 декабря 2011

Довольно много ошибок в этом простом коде;

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

Ниже приведена ссылка на то, как правильно обращаться со стороны Java. Обнаружение прерывания потока с помощью собственного ожидающего вызова JNA (Windows)

На стороне WinAPI: в зависимости от вашего случая вам могут понадобиться CloseHandle, SetEvent или любое другое уведомление, которое вам нужно.Затем, после возврата из WaitForSingleObject, проверьте состояние объекта и, если потребуется, создайте InterruptedException.

0 голосов
/ 23 декабря 2011

Проблема в том, что TimerTask.run () не вызывается через 3 секунды, как ожидалось, он вызывается только после того, как WaitForSingleObject () завершает сам.Что я делаю не так?

Простой ответ: вы делаете блокирующий вызов операционной системы.Пока ваш поток заблокирован, TimerTask в этом потоке не сработает.

Даже если вы запустили TimerTask в другом потоке, маловероятно, что прерывание будет работать, поскольку Thread.interrupt является специфической для Java функцией (как@axtavt).

Если вам нужна дополнительная помощь, пожалуйста, создайте еще одну публикацию и объясните, почему вам нужно это сделать и каковы ваши ограничения (что-то более конкретное, чем "... это ломает моюAPI ").Возможно, мы найдем альтернативный подход.

0 голосов
/ 23 декабря 2011

При просмотре документации Microsoft для WaitForSingleObject , есть предположение, что вместо этого можно подумать о WaitForSingleObjectEx (для того, чтобы войти в "состояние ожидания с оповещением").

...