BlackBerry Forums Support Community               

Closed Thread
 
LinkBack Thread Tools
Old 08-21-2009, 09:10 PM   #1 (permalink)
ARB
New Member
 
Join Date: Feb 2009
Model: 8300
PIN: N/A
Carrier: telus
Posts: 3
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default Multiple threads out of sync

Please Login to Remove!

Hello, I have been driving myself crazy trying to figure this out. I want to be able to pull data from my server and send the data to my Bluetooth printer. The way that I've implemented this application works sometimes (very inconsistent) and I believe it's due to managing threads. The data that is returned from the GetEraseDataThread is null most of the time which I believe is due to the second thread starting before the first is complete. This is my first run at threads...can someone please help?

Code:
 //menu option to pull new template file from server and send to printer
private MenuItem FlashMenu = new MenuItem("Template",100,3) {
       public void run() {
           runResetTemplate();
       } 
    };

    private void runResetTemplate() 
    {    
        GetEraseDataThread geterasedatathread = null;
        SendToPrinterThread sendtoprinterthread = null;
       
        try
        {    

            //if GET IO thread exists...kill it first
            if(null != geterasedatathread)
                    geterasedatathread.closeIO();

            //create thread to get template data using HTTP
            geterasedatathread = new GetEraseDataThread();                                                            
            geterasedatathread.start();  

            //set the input stream so we can close the thread
            send_text = geterasedatathread.CPCL_Template;

            if (!geterasedatathread.displaystring.equals(""))
            {
               Dialog.alert(geterasedatathread.displaystring.toString()); 
            }
            else
            {
                Dialog.alert("send_text = " + send_text);
            }
            //kill io
            geterasedatathread.closeIO();
 

            //if GET IO thread exists...kill it first
            if(null != sendtoprinterthread)
                    sendtoprinterthread.closeIO();

             //create thread to send template to printer
            sendtoprinterthread = new SendToPrinterThread();                                                            
            sendtoprinterthread.start();
            sendtoprinterthread.sendtext = send_text;
            //kill io
            sendtoprinterthread.closeIO();
 
           }
           catch (Exception ex) 
            {
                Dialog.alert(ex.getMessage());
            }            
    }



class GetEraseDataThread extends Thread 
{     
         private HttpConnection c = null;
         private InputStream is = null;
         public String CPCL_Template = "";          // template text
         public String displaystring = "";          // error/msg string
         int rc = 0;
         
         public void run() 
         {
            try 
            {
                // get the XML receipt data from server
                c = (HttpConnection)Connector.open(Options.getAppServerUrl() + "/ms_reset.txt");
    
                // Getting the response code will open the connection,
                // send the request, and read the HTTP response headers.
                // The headers are stored until requested.
                rc = c.getResponseCode();
                if (rc != HttpConnection.HTTP_OK) 
                {
                    throw new IOException("HTTP response code: " + rc);
                }
    
                if (is != null)
                    is.close();
                is = c.openInputStream();              
                
            
    
                // Get the ContentType
                String type = c.getType();
    
                // Get the length and process the data
                int len = (int)c.getLength();
                if (len > 0) 
                {
                    int actual = 0;
                    int bytesread = 0 ;
                    byte[] data = new byte[len];
                    while ((bytesread != len) && (actual != -1)) 
                    {
                        actual = is.read(data, bytesread, len - bytesread);
                        bytesread += actual;
                    }    
                    
                    //assign data to print string
                    //assuming utf-8 encoding                 
                    String test = new String(data,0,data.length,"UTF8");                 
                    CPCL_Template = test;        
                } 
                else 
                {
                    int ch;
                    while ((ch = is.read()) != -1) 
                    {
                    //do something
                    }
                }
            } 
            catch (IOException e) 
            {
                displaystring = e.getMessage();
            }             
            
            try 
            {
                if (is != null)
                {
                    is.close();
                    is = null;
                }
                if (c != null)
                {
                    c.close();
                    c = null;
                }
            }
            catch(IOException e)
            {
                displaystring = e.getMessage();
            }
            
        }
        
        public void closeIO()
        {    
            try
            {
                if (is != null)
                    is.close();
                if (c != null)
                    c.close(); 
            }
            catch(IOException e)
            {
                displaystring = e.getMessage();
            }
                           
            if(null != this)                  // wait for IO thread to die
            {
                try
                {
                    join();
                }
                catch(InterruptedException e)
                {
                   displaystring = e.getMessage();
                }
            }
        } 
    }



class SendToPrinterThread extends Thread 
{
    private StreamConnection sc = null;
    private DataOutputStream os = null;
    private InputStream is = null;  
    private boolean killIO = false; // flag to stop IOget thread
    public String sendtext = "";

    public void run() 
    {
        String data;
        int len;
        killIO = false;
        try 
        {
         
            //get the string used to open a Bluetooth stream connection
            BluetoothSerialPortInfo[] info = BluetoothSerialPort.getSerialPortInfo();               
            if( info == null || info.length == 0 ) 
            {                                      
     //           System.out.println("no info");
                return;
            }
//
            sc = (StreamConnection)Connector.open( info[0].toString(), Connector.READ_WRITE );
            is = sc.openDataInputStream();
            os = sc.openDataOutputStream();
        } 
        catch(IOException e) 
        {
   //         System.out.println(e.getMessage());                                              // alert user what's going on
            return;
        }                       
      
        //give a chance for other threads to catch up/update
        yield();           
                                
        if(null == is || null == os)
            return;
                                        
        try 
        {
            os.writeChars(sendtext);
            os.flush();
        }
        catch(IOException e)
        {
            System.out.println(e.getMessage());  
        }

        byte b[];
               
        //stay in this loop until killIO is set to true                        
        while(true)
        {
            if(killIO)                                                                                                                                      
                break;
            yield();   
            // always give other threads a chance to run                                                                                                                                    
            if(null == is || null == os)
                break;
                
            // get number of characters available                    
            try
            {
                len = is.available();                                                                                                   
            }
            catch(IOException e)
            {
                System.out.println(e.getMessage());
                len = 0;
            }
            
            // no chars available, go back to top of loop              
            if(0 == len)
                continue;                                                                                                                               
        
            b = new byte[len];
            try
            {
                len = is.read(b);                                                                                                               // read <len> number of characters as bytes(may not be all the ones available but that doesn't matter)
            }
            catch(IOException e)
            {
                System.out.println(e.getMessage()); 
                continue;
            }        
         }// end of while
                         
         try     
         {               
            // close the streams
            if(sc != null)
                sc.close();
            if(os != null)
                os.close();
            if(is != null)
                is.close();    
          }  
          catch(IOException e)
          {
            System.out.println(e.getMessage());
          }

     } // end of run
                
     public void closeIO()
     {    
        killIO = true;                  // tell IO thread to die
                        
        if(null != this)                  // wait for IO thread to die
        {
            try
            {
                this.join();
            }
            catch(InterruptedException e)
            {
                System.out.println(e.getMessage());
            }
        }
        
        sc = null;
        os = null;
        is = null;
     } 
                
}
Offline  
Old 08-22-2009, 01:33 AM   #2 (permalink)
Knows Where the Search Button Is
 
Join Date: Jul 2008
Model: none
PIN: N/A
Carrier: none
Posts: 26
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

I think you are right. The issue stems from the fact the threads sometimes out run each other.

Here is what I think happens. Method runResetTemplate() executes in thread T1. Then you create and start GetEraseDataThread, which is T2. Sometimes T2 executes fast enough for CPCL_Template to be set before T1 retrieves it, and sometimes it doesn't. That's why you see null there form time to time.

I think you can fix this by adding join() in between here
Code:
            geterasedatathread.start(); 
            geterasedatathread.join(); 

            //set the input stream so we can close the thread
            send_text = geterasedatathread.CPCL_Template;
What I am wondering is what it is you're trying to gain by using threads. You basically have to execute geterasedatathread.start() (T2) synchronously with T1. You have to go over the network, get the result, then send it to the printer, in this exact order. Each step is dependent on a result from the previous step. I can't see any gain from asynchronous execution of any part of it.
Offline  
Closed Thread


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On





Copyright 2004-2014 BlackBerryForums.com.
The names RIM and BlackBerry are registered Trademarks of BlackBerry Inc.