日期:2014-05-20  浏览次数:20737 次

递归执行任务,存在异常,请大侠指点
功能描述:
  本代码是采用dj native swing包模拟多用户多系统自动登入的,想打开一个url时通过监听LoadingProgress值,如果等于100则证明打开网页完成,然后再打开下一个url,直到所有url打开完成为止。
  程序采用TimerTask(本代码将此任务定义为:timerFinished)方式,打开任务时将timerFinished直接cancel,停止自动调用下一个要打开的url,待public void loadingProgressChanged(WebBrowserEvent e)监听到已完成则重新启动一个任务[timerFinished.schedule(new ListenSysOpenFinished(), 1000, 2000)],并在打开链接列表中删除已打开的url(allUrls.remove(0);), 但现在的问题是现在url还未打开完成,但程序会继续执行下去,不知道是那存在问题,帮忙看一下:

Java code

    private Timer timerFinished = new Timer(); 
    private List allUrls = new ArrayList(); // 所有需要打开的url列表

    private void openUrl(){
        
        timerFinished = new Timer();
        // 在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
        timerFinished.schedule(new ListenSysOpenFinished(), 2000, 1000);
    }

    public class ListenSysOpenFinished extends TimerTask {
        @Override
        public void run() {
            oneByOneOpenSys();
        }
    }

    public void oneByOneOpenSys() {
        if (allUrls.size() > 0) {
            timerFinished.cancel();
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    if (allUrls.size() > 0) {
                        String url = allUrls.get(0).toString();
 
                        NativeInterface.open();
                        NativeInterface.initialize();

            // 显示日志信息
                        LoginLog loginLog = (LoginLog) curOpenSysInfo.get(0);
                        if (loginLog.isClearCookie()) {
                            JWebBrowser.clearSessionCookies();
                        }
                        
                        JPanel webBrowserPanel = new JPanel(new BorderLayout());
                        webBrowserPanel.setBorder(BorderFactory.createTitledBorder("KR-Browser"));
                        webBrowser = new JWebBrowser();
                        webBrowser.navigate(url);
                        webBrowserPanel.add(webBrowser);

                        tbMain.addTab("browser", webBrowserPanel);
                        webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
                            @Override
                            public void loadingProgressChanged(WebBrowserEvent e) {
                                if (e.getWebBrowser().getLoadingProgress() == 100) {
                                    JDate jDate = new JDate();
                                    allUrls.remove(0);
                                    timerFinished = new Timer();
                                    timerFinished.schedule(new ListenSysOpenFinished(), 1000, 2000);
                                }
                            }
                        });
                    }
                }
            });


        } else {
            timerFinished.cancel();

        }
    }



------解决方案--------------------
楼主好像没必要用 
// 在1秒后执行此任务,每次间隔2秒,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.
timerFinished.schedule(new ListenSysOpenFinished(), 2000, 1000);
定时触发系统,因为你是一个一个执行的,一个执行完了自己触发另一个。
当你执行到下面这句,又执行一个任务列,尽管你用了cancel
timerFinished.schedule(new ListenSysOpenFinished(), 1000, 2000);
从第一次执行任务到第三个线程执行前,也就是在到执行timerFinished.cancel();这句前,如果时间超过了2秒。那不是又会产生一次任务。
不知道我分析的对不对。建议延时触发一次就好了。然后引发触发链。

------解决方案--------------------
探讨

引用:

都簡化成這樣了,還有問題?那你意思是會有oneByOneOpenSys()方法莫名的計劃外被調用?不好調試就用打印啊,觀察對象就那麼一個。


是的。。