Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Developer
Posts: 322
Registered: ‎05-26-2009
My Device: Not Specified

Kill a worker Thread doing network I/O

Hi,

I need to kill a network thread doing network I/O when user clicks on "Cancel" button in the event thread. To achieve this I do the following:

 

1.) All the network I/O happens in a Runnable object. I added a "cancel" method to this Runnable object. The cancel method does the following:

 

  • Calls HttpConnection::close and set it to null.
  • Call InputStream::close and set it to null.
  • Call Outputstream::close an set it to null.

 

After the cancel method is called, i call Thread::interrupt which is running the Runnable object.

 

However the above is not cancelling the network I/O thread and the network I/O operation finishes. I have confirmed that the "cancel" method, which sets all above pointers to null is being called by changing the 'text' of the status field which shows the status of network I/O thread.

 

I have spent quite some time on this. I would really appreciate any pointer in resolving this.

I have tried this on JDE 4.2  as well as 4.5.

 

--MB.

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

I believe that I have read on a Thread on this forum, that it is not possible to interrupt network I/O.  I've looked for this Thread, but the best I can find is this:

 

http://supportforums.blackberry.com/rim/board/message?board.id=java_dev&message.id=5330

 

have a look for yourself, but I believe the best you can do is ignore the result of the network I/O rather than terminate it.

Developer
Posts: 85
Registered: ‎12-05-2008
My Device: Blackberry 8900 Javelin

Re: Kill a worker Thread doing network I/O

Seconding Peters' reply. When I "cancel" a network operation my worker thread waits for HTTP to unblock and then ignores whatever is returned.
Developer
Developer
Posts: 283
Registered: ‎07-22-2008
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

Since these operations are blocking in nature, the thread interrupt will not really interrupt the operation.

I have used a couple of ways to solve similar problem.

 

1- To use a cancel flag ( as you did) and test after each read if the operation was cancelled, to safely abort the operation and return. The disadvantage is that the return may not happen immediately if this is required in some cases.

 

2- Use a monitor class ( a wrapper around the HttpConnection object) to kill the connection object. When it is time to cancel it closes the connection ( or the stream). This will generate an exception and the operation is aborted. The advantage is that the abort happens immediately. Also I added the timeout notion using this way. You can set a read with a timeout.

 

Rab

Developer
Developer
Posts: 322
Registered: ‎05-26-2009
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

Hi Rab,

 

I have done both 1.) and 2.).

 

  • When the user clicks on cancel, i set a cancel flag, close HttpConnection and the corresponding InputStream and OutputStream.I do not check for the cancel flag inside the loop which read/writes on streams. I was hoping that closing the streams would immediately abort the ongoing I/O activity but it doesn't seem to happen.  I have tried this with JDE 4.2 as well as JDE 4.5.


 

--MB.

Developer
Developer
Posts: 322
Registered: ‎05-26-2009
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

 

Hi Rab,

This is what my cancel method in the wrapper class around HttpConnection looks like:

_is, _os, _conn are private data members in the wrapper class.

 

    public void cancel() {
        try {
            if (_is != null) {
                _is.close();
                _is = null;
            }
            if(_os != null) {
                _os.close();
                _os = null;
            }
            if(_conn != null) {
                _conn.close();
                _conn = null;
            }
        }
        catch(IOException e) {
        }
    }
 

 

--MB

Developer
Developer
Posts: 283
Registered: ‎07-22-2008
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

I was using the same solution I mentioned to you and It was working fine.

So, when the _is.close() was called, it generates an immediate IOException ( stream closed) which causes the I/O read to abort.

The only thing I could suggest is to check using the debugger that the _is.close() in your code is reached/executed immediately when you press the cancel button. 

 

The code I had was similar to yours. In my cancel I was just closing the input stream, since the method that had the read was doing all the  closings in its finally block.

 

This was tested on 4.2 and 4.6

 

Rab 

 

Contributor
Posts: 10
Registered: ‎03-10-2010
My Device: 9550
My Carrier: Vodaphone

Re: Kill a worker Thread doing network I/O

I wrote a piece of code to test whether HttpConnection.close() can cancel the "open connection" i/o activity.  Hope that this is useful for you !

 

Timeout for open connection in Blackberry (at least in simulator) is 2min, which is too long.

If I allow my user to set his own connection timeout, I need someway to cancel this I/O operation.

Closing the connection and stream really cancel the I/O operation.

 

The folllowing is my testing code.

When The Cancel Thread run with the debugger found that

- There is an exception at line ######A and the exception is IOCancelledException (It's really work).

   However, the e.printStackTrace print out "No Stack"

 

 

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

public class ConnectionThread extends Thread {
	private String url = "http://www.google.com";
	StreamConnection s = null;
	InputStream is = null;

	/**
	 * This method is where the thread retrieves the content from the page whose
	 * url is associated with this thread.
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		try {
			s = (StreamConnection) Connector.open(url);
			is = s.openInputStream();
		} catch (IOException e) {
			System.out.println("###########A");
			Utils.showMessage(e.getMessage());
			e.printStackTrace();
			return;
		} finally {
			try {
				if (is != null)
					is.close();
				if (s != null)
					s.close();
			} catch (Exception e) {
				System.out.println("###########B");
				Utils.showMessage(e.getMessage());
				e.printStackTrace();
			}
		}
		Utils.showMessage("Success");
	}

	public void cancel() {
		try {
			if (is != null)
				is.close();
			if (s != null)
				s.close();
		} catch (Exception e) {
			System.out.println("########C");
			Utils.showMessage(e.getMessage());
			e.printStackTrace();
		}
		Utils.showMessage("CANCEL SUCCESS!");
	}
}

class CancelThread extends Thread {
	private final ConnectionThread conn;
	public CancelThread(ConnectionThread conn) {
		this.conn = conn;		
	}
	public void run() {
		if (conn != null) {
			conn.cancel();
		}
	}
}

 

 

Developer
Posts: 59
Registered: ‎07-01-2009
My Device: Android HTC One X
My Carrier: Cellcom

Re: Kill a worker Thread doing network I/O

Killing a network operation is not possible in J2ME. You can not cut off a stream or close the HTTPCONNECTION, because of the blocking nature of the operation considering that Thread.interrupt() is deprecated.

The best solution is to raise a flag and check it after the oprtaion finishes.  Any other solution will only seem to work, but will fail upon deeper testing.

Trusted Contributor
Posts: 184
Registered: ‎11-26-2010
My Device: Not Specified

Re: Kill a worker Thread doing network I/O

I would agree with Vaiden and Peter's suggestion to use a flag. In my case, I am performing network connection, do parsing, create next screen object, lock Event thread and push it on to the stack. What if the thread is done with the network part and is performing other operation? Set a class flag for wait screen and checking it before pushing on to the Event thread is I am adopting to now! You can also check the flag before each thread related operation. Any how that is the way I am coding with my knowledge. Correct me, if, I am wrong.. Smiley Happy

 

A Y.