3

更新: 他のスレッドでも問題を見つけています。それらは Scheduled 状態に入りますが、Running に移行することはありません。なぜ?

私のプログラムには、タスクを使用してシリアル ポート経由でデバイスに接続するサービスがあります。言い換えると、

public class ConnectService extends Service<String> {
   protected Task createTask() {
        return new ConnectTask();
    }

    class ConnectTask extends Task<ObservableList<String>> {
        @Override
        protected ObservableList<String> call() throws Exception {
            ...
            connect();
            ...
        }
    }
}

デバイスに接続するための以前の呼び出しがハングした場合は、タスク/スレッドをキャンセルして、この試行で最初からやり直します。これを行うためには、

    if (connectService.getState() != Worker.State.READY) {
        connectService.cancel();
    }
    connectService.restart();

ただし、デバッガーでは、状態が SCHEDULED の場合、上記のコードはそれを CANCELLED に送信することがわかりました。しかし、restart() はそれを READY に送信しません - 代わりに SCHEDULED に戻ります - そしてcall() は実行されません!

これはここのドキュメントと矛盾しているようです

再利用可能なワーカーは、CANCELLED、SUCCEEDED、または FAILED から READY に戻ります。

私は試した

   if (connectService.getState() != Worker.State.READY) {
        connectService.cancel();
        connectService.reset();
    }
    connectService.start();

状態は READY に戻りますが、call() は実行されません!

4

1 に答える 1

1

Worker.State.SCHEDULED条件から除外された状態に追加する必要がありますif。つまり、

if (connectService.getState() != Worker.State.READY && 
    connectService.getState() != Worker.State.SCHEDULED) {

    connectService.cancel();
}
connectService.restart();

これは、状態に入る前にWorker常にからREADYに遷移するためです。ドキュメントからSCHEDULEDRUNNING

Workerただし、がすぐに実行される 場合でも、は状態に入る前に Worker一時的に状態になります。つまり、トランジションは常にto toです (もちろん Worker がキャンセルされない限り)。SCHEDULEDRUNNINGREADYSCHEDULEDRUNNING

なんらかの理由で作業がその状態でスタックしている場合、同じスタック状態に戻るSCHEDULED可能性がcancelあります。restart

また、(コードの残りの部分が表示されないため、これは単なる外挿です) ハングしているという前提で実行されているのを見つけたときに中断するという考えは、うまく機能している可能性がありますが、予想よりも時間がかかる可能性があるため、不安定に見えます。呼び出すたびにハングする可能性があります。ハングしているかどうかを判断するために実行できるテストがないconnectService場合は、このようなことで立ち往生していると思いますが、問題があると感じています.

于 2013-06-06T16:58:39.227 に答える