Process Threads

  • Thread starter Stephen J. Shephard
  • Start date
S

Stephen J. Shephard

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.
 
S

Stephen J. Shephard

As a follow up, this is where I've done so far... Is this what the MSDN
article is recommending or am I way out in left field??

using System;
using System.Diagnostics;
using System.Threading;
namespace whatever {
public class ProcessMaster
{
private string strS1, strS2;
private System.IO.StreamReader rdrO, rdrE;
public ProcessMaster() {}
public getBusy() {
//--
// whole bunch of process start info definitions here (what .exe to
use, blah, blah, blah)
//--

myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.RedirectStandardError = true;
myProcess.Start();
rdrO = myProcess.StandardOutput;
rdrE = myProcess.StandardError;
Thread myOThread = new Thread(new ThreadStart(ReadStdOut));
Thread myEThread = new Thread(new ThreadStart(ReadStdErr));
myOThread.Start();
myEThread.Start();
myProcess.WaitForExit();
// necessary to join since threads don't seem to end as quickly as
process.
myOThread.Join(10000);
myEThread.Join(10000);
// continue as normal (reference strS1 and strS2 to scrub output)
}
private void ReadStdOut() {
strS1 = rdrO.ReadToEnd();
}
private void ReadStdErr() {
strS2 = rdrE.ReadToEnd();
}
}
}
 
Y

Yan-Hong Huang[MSFT]

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.
!
!
!
 
S

Stephen J. Shephard

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!!
 
Y

Yan-Hong Huang[MSFT]

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.
!> !
!> !
!> !
!>
!
!
!
 
Y

Yan-Hong Huang[MSFT]

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.
!> !> !
!> !> !
!> !> !
!> !>
!> !
!> !
!> !
!>
!
!
!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top