Problem using separate threads and waiting for the results

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem using separate threads and waiting for the results

Alan Hewat
I posted this problem in a different way 2 weeks ago, but had no response :-)

I am trying to open a thread to run a system command, but NOT wait for
the result. If I use:
status=exec(mySystemCommand);
the ImageJ script naturally(?) waits for the result (status) instead
of continuing immediately.

I read that "doCommand(...)" opened an independent thread to launch a
Menu command, which would then execute while allowing the main ImageJ
thread to continue, but I could not see how to use that to launch a
system command.

Basically I want to initiate image acquisition from different cameras
via a VBScript, periodically check for the creation of the image
files, and then process them.

Any suggestions would be greatly appreciated. Alan

On 5 January 2013 20:08, Alan Hewat <[hidden email]> wrote:

> I have an ImageJ script that launches a VBScript to capture images
> from a camera, writing files that can be picked up by ImageJ when the
> VBScript finishes i.e:
>
> status=exec("cscript "+myVBScript+parameters);
> open(capturedImage);
> ...treat the captured image etc...
>
> Now I want to launch the VBScript in a separate thread, such that it
> captures a number of images, and ImageJ doesn't wait for it, but finds
> and treats those image files as they are written. It should be much
> faster to run my VBScript and ImageJ script independently, in separate
> threads.
>
> Is that possible please ? Perhaps there is an example somewhere ?
>
>  Thanks. Alan
______________________________________________
Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
<[hidden email]> +33.476.98.41.68
        http://www.NeutronOptics.com/hewat
______________________________________________

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Michael Schmid
Hi Alan,

you could have a separate macro with the 'exec' somewhere in a subfolder of ImageJ/plugins. The name of the macro file should contain an underscore character, then it appears in the ImageJ menu (after restarting ImageJ).
ImageJ should then be able to run that macro with "doCommand(...)"

Michael
________________________________________________________________
On Jan 20, 2013, at 16:25, Alan Hewat wrote:

> I posted this problem in a different way 2 weeks ago, but had no response :-)
>
> I am trying to open a thread to run a system command, but NOT wait for
> the result. If I use:
> status=exec(mySystemCommand);
> the ImageJ script naturally(?) waits for the result (status) instead
> of continuing immediately.
>
> I read that "doCommand(...)" opened an independent thread to launch a
> Menu command, which would then execute while allowing the main ImageJ
> thread to continue, but I could not see how to use that to launch a
> system command.
>
> Basically I want to initiate image acquisition from different cameras
> via a VBScript, periodically check for the creation of the image
> files, and then process them.
>
> Any suggestions would be greatly appreciated. Alan
>
> On 5 January 2013 20:08, Alan Hewat <[hidden email]> wrote:
>> I have an ImageJ script that launches a VBScript to capture images
>> from a camera, writing files that can be picked up by ImageJ when the
>> VBScript finishes i.e:
>>
>> status=exec("cscript "+myVBScript+parameters);
>> open(capturedImage);
>> ...treat the captured image etc...
>>
>> Now I want to launch the VBScript in a separate thread, such that it
>> captures a number of images, and ImageJ doesn't wait for it, but finds
>> and treats those image files as they are written. It should be much
>> faster to run my VBScript and ImageJ script independently, in separate
>> threads.
>>
>> Is that possible please ? Perhaps there is an example somewhere ?
>>
>> Thanks. Alan
> ______________________________________________
> Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
> <[hidden email]> +33.476.98.41.68
>        http://www.NeutronOptics.com/hewat
> ______________________________________________
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Heeschen, Bill (WA)
In reply to this post by Alan Hewat
(apologies if this is a redundant message - I subscribe via Digest mode)

Alan:
I ran into more-or-less the same situation with an external camera utility.  I tried something similar to what Michael Schmid proposed, but could not get it to work the way I wanted it to - maybe you've had better results than me!!

I resorted to a plugin...  

I wrote a "special" stripped-down version of the exec() command as a macro-callable public method in a nearly-trivial plugin called "my_exec.java".  The plugin contains the public method doExec(commandString) that sends commandString to the operating system console.  If the command got to where it was going, the method returns the string    "worked".   Otherwise it returns   "fail".  The point is, it does not wait around for anything to come back from the command line.  A word of caution - whatever you put into  commandString   will go out exactly that way!!

You call the   doExec()  method from your macro with...
      tString=call("my_exec.doExec",commandString);

If you run the plugin from the ImageJ Plugins menu, the   run()   method executes a default command (starting Microsoft Word).

The plugin code is below.  Here is how to proceed...
1) Create a new plugin  (Plugins => New => Plugin)
2) copy/paste all the code below into the new plugin (I recommend modifying the value of    testString)
3) save it in your \ImageJ\plugins folder with the name   my_exec.java
4) Compile and Run the plugin from the File menu of the plugin editor (creates a file called   my_exec.class  )
5) call the plugin with   tResult=call("my_exec.doExec",commandString);
[I think the method is immediately available, but I don't recall exactly.  You may need to restart ImageJ for it to be successfully called from your macro...]

Hope this helps.
Bill Heeschen
The Dow Chemical Company
[hidden email]

*************Copy/Paste everything below************

/*Plugin to execute command-line actions
2012-Jan-03 by Bill Heeschen
Submitted personally to the ImageJ community (not on behalf of my employer)
All the usual disclaimers about "use at your own risk", "nothing guaranteed", blah, blah, blah.
 
I wrote this because the built-in ImageJ exec() function insists on waiting
for a return string from the process and I need to launch a watcher program,
then continue on with the macro.

Further, it was written expecting to be run under Microsoft Windows operating system, so the
File separator character in   testString   is a backslash.

Useful item:
www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds.mspx?mfr=true
*/

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import ij.plugin.frame.*;

public class my_exec implements PlugIn {
        public void run(String arg) {
                String testString="c:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE";
                String dummy= doExec(testString);
        }

        public static String doExec(String cmdString){
                String resultString="started";
                try {                                                                                            
                        Process p = Runtime.getRuntime().exec(cmdString);
                        resultString="worked";
                }
                catch (Exception e) {                                                                        
                        resultString="fail";                                                                          
                }
                return resultString;
        }
}  //end of  my_exec  plugin code



--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Alan Hewat
Bill, that is brilliant ! Many thanks for the excellent instructions.
I can now launch my VBScript in an independent (Win-64) thread with
eg:

tResult=call("my_exec.doExec","C:\\Windows\\SysWOW64\\cscript.exe
C:\\ImageJ\\VBScripts\\ASCap.vbs");

Note that in 64-bit Win-7 I must use the 32-bit version of cscript
C:\\Windows\\SysWOW64\\cscript.exe :-) The cscript is launched but
control returns immediately to the next ImageJ statement, without
waiting for the result as usual with ImageJ exec():

result=exec("C:\\Windows\\SysWOW64\\cscript.exe
C:\\ImageJ\\VBScripts\\ASCap.vbs");

Like you, I am using this to expose a camera, and don't want to wait
for the exposure to complete. I just check periodically with ImageJ
for the image file to appear. In fact I want to expose two cameras
simultaneously.

It would be good if your independent exec plugin was intrinsic to
ImageJ. The result=exec("..."); command is essential when you want to
retrieve the result before continuing, but that is not always what is
wanted.

Thanks again, Alan

On 22 January 2013 17:26, Heeschen, Bill (WA) <[hidden email]> wrote:

> (apologies if this is a redundant message - I subscribe via Digest mode)
>
> Alan:
> I ran into more-or-less the same situation with an external camera utility.  I tried something similar to what Michael Schmid proposed, but could not get it to work the way I wanted it to - maybe you've had better results than me!!
>
> I resorted to a plugin...
>
> I wrote a "special" stripped-down version of the exec() command as a macro-callable public method in a nearly-trivial plugin called "my_exec.java".  The plugin contains the public method doExec(commandString) that sends commandString to the operating system console.  If the command got to where it was going, the method returns the string    "worked".   Otherwise it returns   "fail".  The point is, it does not wait around for anything to come back from the command line.  A word of caution - whatever you put into  commandString   will go out exactly that way!!
>
> You call the   doExec()  method from your macro with...
>       tString=call("my_exec.doExec",commandString);
>
> If you run the plugin from the ImageJ Plugins menu, the   run()   method executes a default command (starting Microsoft Word).
>
> The plugin code is below.  Here is how to proceed...
> 1) Create a new plugin  (Plugins => New => Plugin)
> 2) copy/paste all the code below into the new plugin (I recommend modifying the value of    testString)
> 3) save it in your \ImageJ\plugins folder with the name   my_exec.java
> 4) Compile and Run the plugin from the File menu of the plugin editor (creates a file called   my_exec.class  )
> 5) call the plugin with   tResult=call("my_exec.doExec",commandString);
> [I think the method is immediately available, but I don't recall exactly.  You may need to restart ImageJ for it to be successfully called from your macro...]
>
> Hope this helps.
> Bill Heeschen
> The Dow Chemical Company
> [hidden email]
>
> *************Copy/Paste everything below************
>
> /*Plugin to execute command-line actions
> 2012-Jan-03 by Bill Heeschen
> Submitted personally to the ImageJ community (not on behalf of my employer)
> All the usual disclaimers about "use at your own risk", "nothing guaranteed", blah, blah, blah.
>
> I wrote this because the built-in ImageJ exec() function insists on waiting
> for a return string from the process and I need to launch a watcher program,
> then continue on with the macro.
>
> Further, it was written expecting to be run under Microsoft Windows operating system, so the
> File separator character in   testString   is a backslash.
>
> Useful item:
> www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds.mspx?mfr=true
> */
>
> import ij.*;
> import ij.process.*;
> import ij.gui.*;
> import java.awt.*;
> import ij.plugin.*;
> import ij.plugin.frame.*;
>
> public class my_exec implements PlugIn {
>         public void run(String arg) {
>                 String testString="c:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE";
>                 String dummy= doExec(testString);
>         }
>
>         public static String doExec(String cmdString){
>                 String resultString="started";
>                 try {
>                         Process p = Runtime.getRuntime().exec(cmdString);
>                         resultString="worked";
>                 }
>                 catch (Exception e) {
>                         resultString="fail";
>                 }
>                 return resultString;
>         }
> }  //end of  my_exec  plugin code
______________________________________________
Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
<[hidden email]> +33.476.98.41.68
        http://www.NeutronOptics.com/hewat
______________________________________________

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Alan Hewat
In reply to this post by Heeschen, Bill (WA)
Bil, coming back to your "my_exec.java" plugin that launches a Windows
process and returns control immediately to Image J, instead of waiting
for the process to finish like ImageJ's own exec. Your plugin works
well, and allows me to launch multiple time-consuming processes
simultaneously. But for some reason I can't re-direct the output to a
file with eg:

 tResult=call("my_exec.doExec","cmd /c start dir>D:result.txt")

An empty file D:result.txt is created but the output is still
displayed in a Windows shell. Am I missing something simple here ?

Thanks again for the very useful plugin. Alan

On 22 January 2013 17:26, Heeschen, Bill (WA) <[hidden email]> wrote:

>
> I wrote a "special" stripped-down version of the exec() command as a macro-callable public method in a nearly-trivial plugin called "my_exec.java".  The plugin contains the public method doExec(commandString) that sends commandString to the operating system console.  If the command got to where it was going, the method returns the string "worked".   Otherwise it returns "fail".  The point is, it does not wait around for anything to come back from the command line.  A word of caution - whatever you put into  commandString   will go out exactly that way!!
>
> You call the   doExec()  method from your macro with...
>       tString=call("my_exec.doExec",commandString);
>
> If you run the plugin from the ImageJ Plugins menu, the   run()   method executes a default command (starting Microsoft Word).
>
> The plugin code is below.  Here is how to proceed...
> 1) Create a new plugin  (Plugins => New => Plugin)
> 2) copy/paste all the code below into the new plugin (I recommend modifying the value of    testString)
> 3) save it in your \ImageJ\plugins folder with the name   my_exec.java
> 4) Compile and Run the plugin from the File menu of the plugin editor (creates a file called   my_exec.class  )
> 5) call the plugin with   tResult=call("my_exec.doExec",commandString);
> [I think the method is immediately available, but I don't recall exactly.  You may need to restart ImageJ for it to be successfully called from your macro...]
>
> Hope this helps.
> Bill Heeschen
> The Dow Chemical Company
> [hidden email]
>
> *************Copy/Paste everything below************
>
> /*Plugin to execute command-line actions
> 2012-Jan-03 by Bill Heeschen
> Submitted personally to the ImageJ community (not on behalf of my employer)
> All the usual disclaimers about "use at your own risk", "nothing guaranteed", blah, blah, blah.
>
> I wrote this because the built-in ImageJ exec() function insists on waiting
> for a return string from the process and I need to launch a watcher program,
> then continue on with the macro.
>
> Further, it was written expecting to be run under Microsoft Windows operating system, so the
> File separator character in   testString   is a backslash.
>
> Useful item:
> www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds.mspx?mfr=true
> */
>
> import ij.*;
> import ij.process.*;
> import ij.gui.*;
> import java.awt.*;
> import ij.plugin.*;
> import ij.plugin.frame.*;
>
> public class my_exec implements PlugIn {
>         public void run(String arg) {
>                 String testString="c:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE";
>                 String dummy= doExec(testString);
>         }
>
>         public static String doExec(String cmdString){
>                 String resultString="started";
>                 try {
>                         Process p = Runtime.getRuntime().exec(cmdString);
>                         resultString="worked";
>                 }
>                 catch (Exception e) {
>                         resultString="fail";
>                 }
>                 return resultString;
>         }
> }  //end of  my_exec  plugin code
______________________________________________
Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
<[hidden email]> +33.476.98.41.68
        http://www.NeutronOptics.com/hewat
______________________________________________

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Heeschen, Bill (WA)
I'm not particularly proficient with the Windows command line language (I'm assuming this is on Windows!), but there are four things that come to mind.
0) Independently verify that the string you are sending does what you intend it to do (use the Windows  "Run..." command or execute it from a console window).
1) Is your directory path legal?  It seems (for Windows) like it ought to be    D:\result.txt     in order to get the file written to the top level of the D: drive.  Recall that in order to get the backslash to be part of the string you have to precede it with a backslash:

        testString="D:\\myResult.txt";
        IJ.log(testString);//this should cause the Log window to show...       D:\myResult.txt
       
2) Some of your "special characters" might be getting swallowed.  Try a really quick little macro to make sure the string is being put together correctly - something like this:

testString="cmd /c start dir>D:\\result.txt";  //I took the liberty of adding the double backslash
IJ.log(testString);

With any luck the exact string that you're looking for will get printed to the Log window.  If something looks funky - like a missing special character - try preceding it with a backslash (\).

3) Define the string in a separate statement, then pass that string to the command.  I've found that some quoted arguments become too complex for the input of a macro command.  No rhyme nor reason that I've been able to verify, but the problem is resolved by defining the string separately, then passing the string to the command.

That's about all I've got!
Best Regards,
Bill
[hidden email]

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Alan Hewat
Sent: Monday, March 18, 2013 6:05 AM
To: [hidden email]
Cc: Heeschen, Bill (WA)
Subject: Re: Problem using separate threads and waiting for the results

Bil, coming back to your "my_exec.java" plugin that launches a Windows
process and returns control immediately to Image J, instead of waiting
for the process to finish like ImageJ's own exec. Your plugin works
well, and allows me to launch multiple time-consuming processes
simultaneously. But for some reason I can't re-direct the output to a
file with eg:

 tResult=call("my_exec.doExec","cmd /c start dir>D:result.txt")

An empty file D:result.txt is created but the output is still
displayed in a Windows shell. Am I missing something simple here ?

Thanks again for the very useful plugin. Alan

On 22 January 2013 17:26, Heeschen, Bill (WA) <[hidden email]> wrote:
>
<snip>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Alan Hewat
Thanks Bill.

I tried all of that, and I still get an empty file "D:\temp\test.txt"
and a cmd window popping up with the result that should have been
re-directed there with:

public void run(String arg) {
        String cmdStr="cmd /c start dir>D:\\temp\\test.txt";
         IJ.log(cmdStr); //Check cmdStr is: "cmd /c start dir>D:\temp\test.txt"
         String dummy= Exec(cmdStr);
}

I guess this is a Windows thing. I can eventually get my application
(in place of "dir") to print a file instead of stdOut, but it is
curious that re-direction does not work here.

Kind regards, Alan.

On 18 March 2013 15:58, Heeschen, Bill (WA) <[hidden email]> wrote:

> I'm not particularly proficient with the Windows command line language (I'm assuming this is on Windows!), but there are four things that come to mind.
> 0) Independently verify that the string you are sending does what you intend it to do (use the Windows  "Run..." command or execute it from a console window).
> 1) Is your directory path legal?  It seems (for Windows) like it ought to be    D:\result.txt     in order to get the file written to the top level of the D: drive.  Recall that in order to get the backslash to be part of the string you have to precede it with a backslash:
>
>         testString="D:\\myResult.txt";
>         IJ.log(testString);//this should cause the Log window to show...       D:\myResult.txt
>
> 2) Some of your "special characters" might be getting swallowed.  Try a really quick little macro to make sure the string is being put together correctly - something like this:
>
> testString="cmd /c start dir>D:\\result.txt";  //I took the liberty of adding the double backslash
> IJ.log(testString);
>
> With any luck the exact string that you're looking for will get printed to the Log window.  If something looks funky - like a missing special character - try preceding it with a backslash (\).
>
> 3) Define the string in a separate statement, then pass that string to the command.  I've found that some quoted arguments become too complex for the input of a macro command.  No rhyme nor reason that I've been able to verify, but the problem is resolved by defining the string separately, then passing the string to the command.
>
> That's about all I've got!
> Best Regards,
> Bill
> [hidden email]
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Alan Hewat
> Sent: Monday, March 18, 2013 6:05 AM
> To: [hidden email]
> Cc: Heeschen, Bill (WA)
> Subject: Re: Problem using separate threads and waiting for the results
>
> Bil, coming back to your "my_exec.java" plugin that launches a Windows
> process and returns control immediately to Image J, instead of waiting
> for the process to finish like ImageJ's own exec. Your plugin works
> well, and allows me to launch multiple time-consuming processes
> simultaneously. But for some reason I can't re-direct the output to a
> file with eg:
>
>  tResult=call("my_exec.doExec","cmd /c start dir>D:result.txt")
>
> An empty file D:result.txt is created but the output is still
> displayed in a Windows shell. Am I missing something simple here ?
>
> Thanks again for the very useful plugin. Alan
>
> On 22 January 2013 17:26, Heeschen, Bill (WA) <[hidden email]> wrote:
>>
> <snip>
______________________________________________
Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
<[hidden email]> +33.476.98.41.68
        http://www.NeutronOptics.com/hewat
______________________________________________

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

dscho
Hi Alan,

On Mon, 18 Mar 2013, Alan Hewat wrote:

> public void run(String arg) {
> String cmdStr="cmd /c start dir>D:\\temp\\test.txt";

The problem is the "start" which tells cmd to launch the program "dir" and
go on immediately. The redirection to the file is performed by cmd, not
start, however, so it does not get any output.

In general, however, it is more robust to catch the output directly and
write it to a file from Java. Example:

        https://github.com/scijava/scijava-common/blob/master/src/main/java/org/scijava/util/ProcessUtils.java

Ciao,
Johannes

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Problem using separate threads and waiting for the results

Alan Hewat
Thanks Johannes. That makes sense. Yes, I didn't really understand
that syntax "cmd /c start ..."

I am taking your advice and writing what I want to a file rather than
relying on stdOut.

Alan.

On 18 March 2013 17:00, Johannes Schindelin <[hidden email]> wrote:

> Hi Alan,
>
> On Mon, 18 Mar 2013, Alan Hewat wrote:
>
>> public void run(String arg) {
>>       String cmdStr="cmd /c start dir>D:\\temp\\test.txt";
>
> The problem is the "start" which tells cmd to launch the program "dir" and
> go on immediately. The redirection to the file is performed by cmd, not
> start, however, so it does not get any output.
>
> In general, however, it is more robust to catch the output directly and
> write it to a file from Java. Example:
>
>         https://github.com/scijava/scijava-common/blob/master/src/main/java/org/scijava/util/ProcessUtils.java
>
> Ciao,
> Johannes
______________________________________________
Dr Alan Hewat, NeutronOptics, Grenoble, FRANCE
<[hidden email]> +33.476.98.41.68
        http://www.NeutronOptics.com/hewat
______________________________________________

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html