2010-03-01 4 views
6

के साथ एक कार्य टाइमआउट मैं अपने आवेदन के भीतर SwingWorker कक्षा को लागू करने की कोशिश कर रहा हूं। क्या समय तय करने का कोई तरीका है जिसके बाद, स्विंगवर्कर "टाइम्स आउट"? मैं सोच रहा था कि शायद OutOfTime अपवाद फेंक रहा है जिसे मैं पकड़ सकता हूं और उसके साथ सौदा कर सकता हूं। मुझे यकीन नहीं है कि इसे कैसे कार्यान्वित किया जाए।जावा के स्विंगवर्कर

आपकी सभी मदद के लिए धन्यवाद!

उत्तर

4

क्यों एक Runnable भीतर अपने कार्य को एम्बेड नहीं है, यह में छोड़ एक नए एकल-थ्रेड ExecutorService और फिर एक उपयुक्त समय समाप्ति के साथ जिसके परिणामस्वरूप Future पर एक get() प्रदर्शन करते हैं। इससे आपको आपकी टाइमआउट कार्यक्षमता मिल जाएगी, क्योंकि get() समय पर पूरा नहीं होने पर अपवाद फेंक देगा।

+0

इसके अलावा: बस टाइमआउट के साथ कॉल() को कॉल करना अभी भी (संभावित रूप से महंगा) काम बाद में किया जा रहा है। कार्य को भी रद्द करने की आवश्यकता है (और इस तरह से लिखा गया है कि इसे वास्तव में काम करना रद्द कर देता है) – Sbodd

+0

आप अपने काम को Future.cancel() विधि –

+0

(जो थ्रेड इंटरप्टेड एक्सेप्शन उत्पन्न करता है, मुझे लगता है) –

1

आपकी उत्तर क्या है इसके आधार पर संक्षिप्त उत्तर "यह कठिन है"। मैं अत्यधिक Java Concurrency In Practice पढ़ने की सलाह देते हैं।

मूलभूत चीज जो आप कर सकते हैं (ए) सुनिश्चित करें कि आपका स्विंगवर्कर का रननेबल इंटरप्ट-फ्रेंडली है, और (बी) टाइमर सेट करें (या ब्लॉकिंग प्राप्त करें() कॉल का उपयोग ब्रायन का उल्लेख करें) अपने भविष्य को रद्द करने के लिए।

1

भीतरी वर्ग MySwingWorker अच्छी तरह से आपको क्या चाहिए कर सकते हैं:

package com.misc; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.concurrent.Callable; 
import java.util.concurrent.FutureTask; 
import java.util.concurrent.TimeUnit; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class FutureStuffGUI extends JFrame { 
/** 
* Provides a variant of SwingWorker which operates with a timeout. 
* 
* @param <T> 
*/ 
private static abstract class MySwingWorker<T> { 

    private T result; 
    private Exception raised; 

    /** 
    * Constructor. 
    * 
    * @param timeout 
    * @param timeUnit 
    */ 
    public MySwingWorker(final long timeout, final TimeUnit timeUnit) { 
     result = null; 
     raised = null; 

     System.out.println(Thread.currentThread().getName() + " starting"); 
     final FutureTask<T> future = new FutureTask<T>(new Callable<T>() { 
      public T call() throws Exception { 
       System.out.println(Thread.currentThread().getName() + " running"); 
       T result = doInBackground(); 
       return result; 
      } 
     }); 
     System.out.println(Thread.currentThread().getName() + " future: " + future); 
     final Thread runner = new Thread(null, future, "FutureThread"); 
     Thread watcher = new Thread(null, new Runnable() { 

      @Override 
      public void run() { 
       runner.start(); 
       try { 
        result = future.get(timeout, timeUnit); 
       } catch (Exception ex) { 
        raised = ex; 
       } 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         assert SwingUtilities.isEventDispatchThread(); 
         done(); 
        } 
       }); 
      } 
     }, "WatcherThread"); 
     watcher.start(); 
    } 

    /** 
    * Implement this method as the long-running background task. 
    * 
    * @return 
    * @throws Exception 
    */ 
    abstract protected T doInBackground() throws Exception; 

    /** 
    * This method is invoked from the UI Event Dispatch Thread on completion or timeout. 
    */ 
    abstract protected void done(); 

    /** 
    * This method should be invoked by the implementation of done() to retrieve 
    * the result. 
    * 
    * @return 
    * @throws Exception 
    */ 
    protected T get() throws Exception { 
     assert SwingUtilities.isEventDispatchThread(); 
     if (raised != null) { 
      throw raised; 
     } else { 
      return result; 
     } 
    } 
} 

public FutureStuffGUI() { 
    super("Hello"); 
    init_components(); 
} 

private void init_components() { 
    JPanel panel = new JPanel(); 
    JButton button = new JButton("Press"); 
    panel.add(button); 
    add(panel); 
    pack(); 

    button.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      new MySwingWorker<String>(5, TimeUnit.SECONDS) { 

       @Override 
       protected String doInBackground() throws InterruptedException { 
        assert !SwingUtilities.isEventDispatchThread(); 
        System.out.println(Thread.currentThread().getName() + " doInBackground"); 
//      if (true) { throw new RuntimeException("Blow up"); } 
        Thread.sleep(6 * 1000); 
        return "Hello world!"; 
       } 

       @Override 
       protected void done() { 
        assert SwingUtilities.isEventDispatchThread(); 
        String result; 
        try { 
         result = get(); 
         System.out.println(Thread.currentThread().getName() + " done; result: " + result); 
        } catch (Exception ex) { 
         System.out.println(Thread.currentThread().getName() + " done; errored:"); 
         ex.printStackTrace(); 
        } 
       } 
      }; 
     }; 
    }); 
} 

public static void main(String[] args) { 
    FutureStuffGUI ui = new FutureStuffGUI(); 
    ui.setVisible(true); 
} 

}

+0

किए गए कार्यान्वयन () हमेशा 'java.util.concurrent.TimeoutException' पकड़ लेंगे। क्या यह जानबूझकर है? – DejanLekic

0

SwingWorker का उपयोग नहीं कर के लिए कोई विशेष कारण। get(long, java.util.concurrent.TimeUnit)? यह टाइमआउट अपवाद को फेंक देगा कि आप आसानी से अपने आवेदन में संभाल सकते हैं।