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() 不会被执行!

这似乎与此处的文档相矛盾

可重用的 Worker 将从 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会从 过渡到。从文档READYSCHEDULEDRUNNING

然而,即使在Worker立即执行的情况下, 也会在进入状态之前 Worker暂时进入状态。也就是说,转换总是从到 到(当然,除非 Worker 被取消)。SCHEDULEDRUNNINGREADYSCHEDULEDRUNNING

如果由于某种原因您的工作卡在该SCHEDULED状态,很可能cancelrestart只是将其返回到相同的卡住状态。

此外,(没有看到你的其余代码,所以这只是推断)当你捕捉到它运行时中断它的想法,假设它挂起似乎不稳定,因为它可能运行良好但花费的时间比预期的要长,或者每次调用它都可能挂起。如果没有可以运行的测试connectService来确定它是否挂起,那么我想你会遇到这样的事情,但感觉有问题。

于 2013-06-06T16:58:39.227 回答