Hi Stephen,
It is my pleasure.
Thanks for participating the community.
Best regards,
Yanhong Huang
Microsoft Online Partner Support
Get Secure! -
www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
!From: "Stephen J. Shephard" <
[email protected]>
!References: <
[email protected]>
<ghWd9#
[email protected]>
<
[email protected]>
<
[email protected]>
!Subject: Re: Process Threads
!Date: Wed, 8 Oct 2003 19:13:00 -0800
!Lines: 260
!X-Priority: 3
!X-MSMail-Priority: Normal
!X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
!X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
!Message-ID: <
[email protected]>
!Newsgroups: microsoft.public.dotnet.framework
!NNTP-Posting-Host: host141.acsalaska.com 209.193.44.254
!Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
!Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:55751
!X-Tomcat-NG: microsoft.public.dotnet.framework
!
!Yes, thanks very much for the quick help and advice!
!Stephen
!
!
!!> Hi Stephen,
!>
!> Thanks for the quick response.
!>
!> 1) It is not recommended to use Thread.Abort to terminate other threads.
!> Calling Abort on another thread is akin to throwing an exception on that
!> thread, without knowing what point that thread has reached in its
!> processing. Calling Abort on the same thread is better since we know it
is
!> safe to quit this thread now. The return statement is used to make the
!> funciton completed.
!>
!> 2) I posted the reply before seeing your second post.
I reviewed the
!> code your posted just now. I think if you run it without any error, it
!> should also be OK.
!>
!> ***One of the things I find myself having to do with the stdout and
stderr
!> data is parse it after the main process ends (as opposed ***to just
!> outputting it). I used the join methods after my waitforexit call in
order
!> to make sure the threads were done and the ***stdout/stderr data
available
!> before I continued on in my process.
!> That is why I used Thread.Abort to quit those two threads.
!>
!> Does that answer your question?
!>
!> Best regards,
!> Yanhong Huang
!> Microsoft Online Partner Support
!>
!> Get Secure! -
www.microsoft.com/security
!> This posting is provided "AS IS" with no warranties, and confers no
!rights.
!>
!> --------------------
!> !From: "Stephen J. Shephard" <
[email protected]>
!> !References: <
[email protected]>
!> <ghWd9#
[email protected]>
!> !Subject: Re: Process Threads
!> !Date: Wed, 8 Oct 2003 10:11:57 -0800
!> !Lines: 185
!> !X-Priority: 3
!> !X-MSMail-Priority: Normal
!> !X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
!> !X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
!> !Message-ID: <
[email protected]>
!> !Newsgroups: microsoft.public.dotnet.framework
!> !NNTP-Posting-Host: host141.acsalaska.com 209.193.44.254
!> !Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
!> !Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:55717
!> !X-Tomcat-NG: microsoft.public.dotnet.framework
!> !
!> !Thanks very much! I think I'm on the right track, but to satisfy my
!> !curiousity, I was hoping I could ask a couple questions about the code
!you
!> !provided:
!> !
!> !1) In your terr.Read and tout.Read methods, you call the
!> !Thread.CurrentThread.Abort(), then a return statement. Does your return
!> !statement get executed if the context thread is killed? Doesn't
!processing
!> !end before the return statement? Is there a benefit to calling the abort
!> !inside this method rather than joining after your WaitForExit call?
!> !2) It seems about the same as what I was working with, but a little
!> !different in the methodology. Would you have any insights as to why
you'd
!> !prefer this over the method used in the code I posted?
!> !
!> !One of the things I find myself having to do with the stdout and stderr
!> data
!> !is parse it after the main process ends (as opposed to just outputting
!it).
!> !I used the join methods after my waitforexit call in order to make sure
!the
!> !threads were done and the stdout/stderr data available before I
continued
!> on
!> !in my process.
!> !
!> !Again, I think you've confirmed that I'm on the right track. I had some
!> !difficulty because I was thinking that the MSDN article meant for me to
!> !establish two new threads inside my newly created process, rather than
!> !outside and part of the existing worker process. I'm assuming that's
what
!> !I'm doing anyway. Seems to work though..
!> !
!> !Thanks for your help!!
!> !
!> !!> !> Hello Stephen,
!> !>
!> !> Thanks for posting in the group.
!> !>
!> !> For how to create two threads to read from StandardError and
!> !> StandardOutput, please refer to the following code slice:
!> !>
!> !> //p1.cs:
!> !> ..
!> !> class class1
!> !> {
!> !> .....
!> !> public static void Main()
!> !> {
!> !> ProcessStartInfo pi = new ProcessStartInfo();
!> !> pi.FileName = @"c:\p2.exe";
!> !> pi.UseShellExecute = false;
!> !> pi.RedirectStandardOutput = true;
!> !> pi.RedirectStandardError = true;
!> !> System.Diagnostics.Process p = new Process();
!> !> p.StartInfo = pi;
!> !> p.Start();
!> !> tout t1 = new tout(p);
!> !> terr t2 = new terr(p);
!> !> Thread thread1 = new Thread(new ThreadStart(t1.Read));
!> !> Thread thread2 = new Thread(new ThreadStart(t2.Read));
!> !> thread1.Start();
!> !> thread2.Start();
!> !> p.WaitForExit();
!> !> Console.WriteLine("p2.exe ends");
!> !> }
!> !> }
!> !> class tout
!> !> {
!> !> Process p;
!> !> public tout(Process p)
!> !> {
!> !> this.p = p;
!> !> }
!> !> public void Read()
!> !> {
!> !> int a = -1;
!> !> while((a = p.StandardOutput.Read()) > 0)
!> !> {
!> !> Console.Write( ((char) a).ToString() );
!> !> }
!> !> Thread.CurrentThread.Abort();
!> !> return;
!> !> }
!> !> }
!> !> class terr
!> !> {
!> !> Process p;
!> !> public terr(Process p)
!> !> {
!> !> this.p = p;
!> !> }
!> !> public void Read()
!> !> {
!> !> int a = -1;
!> !> while((a = p.StandardError.Read()) > 0)
!> !> {
!> !> Console.Write(((char) a).ToString());
!> !> }
!> !> Thread.CurrentThread.Abort();
!> !> return;
!> !> }
!> !> }
!> !>
!> !> Does that answer your question?
!> !>
!> !> Best regards,
!> !> Yanhong Huang
!> !> Microsoft Online Partner Support
!> !>
!> !> Get Secure! -
www.microsoft.com/security
!> !> This posting is provided "AS IS" with no warranties, and confers no
!> !rights.
!> !>
!> !> --------------------
!> !> !From: "Stephen J. Shephard" <
[email protected]>
!> !> !Subject: Process Threads
!> !> !Date: Tue, 7 Oct 2003 23:16:23 -0800
!> !> !Lines: 48
!> !> !X-Priority: 3
!> !> !X-MSMail-Priority: Normal
!> !> !X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
!> !> !X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
!> !> !Message-ID: <
[email protected]>
!> !> !Newsgroups: microsoft.public.dotnet.framework
!> !> !NNTP-Posting-Host: host141.acsalaska.com 209.193.44.254
!> !> !Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
!> !> !Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:55653
!> !> !X-Tomcat-NG: microsoft.public.dotnet.framework
!> !> !
!> !> !I think I'm deadlocking my process because of the situation described
!> !> below:
!> !> !Can anyone provide ideas for how to get around this, or an example of
!> !> !creating two threads to read from StandardError and StandardOutput
!> !> !independently, as recommended in the text below?
!> !> !Thanks very, very much..
!> !> !----- FROM MSDN -----
!> !> !
!> !> !The Process component communicates with a child process using a pipe.
!If
!> !a
!> !> !child process writes enough data to the pipe to fill the buffer, the
!> !child
!> !> !will block until the parent reads the data from the pipe. This can
!cause
!> !> !deadlock if your application is reading all output to standard error
!and
!> !> !standard output. The following C# code, for example, could be
!> !problematic.
!> !> !
!> !> !Process p = new Process();
!> !> !p.StartInfo.UseShellExecute = false;
!> !> !p.StartInfo.RedirectStandardError = true;
!> !> !p.StartInfo.FileName = "test.exe";
!> !> !p.Start();
!> !> !p.WaitForExit();
!> !> !string output = p.StandardError.ReadToEnd();
!> !> !In this instance, both the parent and the child processes would be
!> !blocked,
!> !> !as the filled pipe prevents the child process from completing, while
!the
!> !> !parent process is waiting indefinitely for the child process to exit.
!> !> !
!> !> !This problem can be solved by moving the ReadToEnd() before the
!> !> !WaitForExit(), as follows.
!> !> !
!> !> !Process p = new Process();
!> !> !p.StartInfo.UseShellExecute = false;
!> !> !p.StartInfo.RedirectStandardError = true;
!> !> !p.StartInfo.FileName = "test.exe";
!> !> !p.Start();
!> !> !string output = p.StandardError.ReadToEnd();
!> !> !p.WaitForExit();
!> !> !A similar problem arises if you redirect both standard output and
!> !standard
!> !> !error and then try to read both, for example using the following C#
!> code.
!> !> !
!> !> !string output = p.StandardOutput.ReadToEnd();
!> !> !string error = p.StandardError.ReadToEnd();
!> !> !p.WaitForExit();
!> !> !In this case, if the child process writes any text to standard error
!it
!> !> will
!> !> !block the process, because the parent process cannot read from
!standard
!> !> !error until it has finished reading from standard output. However,
the
!> !> !parent process will not read from standard output until the process
!> ends.
!> !A
!> !> !recommended solution to this situation is to create two threads so
!that
!> !> your
!> !> !application can read the output of each stream on a separate thread.
!> !> !
!> !> !
!> !> !
!> !>
!> !
!> !
!> !
!>
!
!
!