Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit afcfbc9

Browse files
Processing error stream async in order to avoid deadlock
1 parent c7cf943 commit afcfbc9

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

src/GitHub.Api/NewTaskSystem/ProcessTask.cs

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ProcessWrapper
5656
private readonly Action onEnd;
5757
private readonly Action<Exception, string> onError;
5858
private readonly CancellationToken token;
59+
private readonly List<string> errors = new List<string>();
5960

6061
public Process Process { get; }
6162
public StreamWriter Input { get; private set; }
@@ -77,6 +78,24 @@ public ProcessWrapper(Process process, IOutputProcessor outputProcessor,
7778

7879
public void Run()
7980
{
81+
if (Process.StartInfo.RedirectStandardError)
82+
{
83+
Process.ErrorDataReceived += (s, e) =>
84+
{
85+
//if (e.Data != null)
86+
//{
87+
// Logger.Trace("ErrorData \"" + (e.Data == null ? "'null'" : e.Data) + "\"");
88+
//}
89+
90+
string encodedData = null;
91+
if (e.Data != null)
92+
{
93+
encodedData = Encoding.UTF8.GetString(Encoding.Default.GetBytes(e.Data));
94+
errors.Add(encodedData);
95+
}
96+
};
97+
}
98+
8099
try
81100
{
82101
Process.Start();
@@ -101,60 +120,48 @@ public void Run()
101120

102121
if (Process.StartInfo.RedirectStandardInput)
103122
Input = new StreamWriter(Process.StandardInput.BaseStream, new UTF8Encoding(false));
104-
105-
var errors = new List<string>();
123+
if (Process.StartInfo.RedirectStandardError)
124+
Process.BeginErrorReadLine();
106125

107126
onStart?.Invoke();
108-
if (Process.StartInfo.CreateNoWindow)
127+
128+
if (Process.StartInfo.RedirectStandardOutput)
109129
{
110-
if (Process.StartInfo.RedirectStandardOutput)
130+
var outputStream = Process.StandardOutput;
131+
var line = outputStream.ReadLine();
132+
while (line != null)
111133
{
112-
var outputStream = Process.StandardOutput;
113-
var line = outputStream.ReadLine();
114-
while (line != null)
115-
{
116-
outputProcessor.LineReceived(line);
117-
118-
if (token.IsCancellationRequested)
119-
{
120-
if (!Process.HasExited)
121-
Process.Kill();
134+
outputProcessor.LineReceived(line);
122135

123-
Process.Close();
124-
onEnd?.Invoke();
125-
token.ThrowIfCancellationRequested();
126-
}
136+
if (token.IsCancellationRequested)
137+
{
138+
if (!Process.HasExited)
139+
Process.Kill();
127140

128-
line = outputStream.ReadLine();
141+
Process.Close();
142+
onEnd?.Invoke();
143+
token.ThrowIfCancellationRequested();
129144
}
130-
outputProcessor.LineReceived(null);
145+
146+
line = outputStream.ReadLine();
131147
}
148+
outputProcessor.LineReceived(null);
149+
}
132150

133-
if (Process.StartInfo.RedirectStandardError)
151+
if (Process.StartInfo.CreateNoWindow)
152+
{
153+
while (!WaitForExit(500))
134154
{
135-
var errorStream = Process.StandardError;
136-
var errorLine = errorStream.ReadLine();
137-
while (errorLine != null)
138-
{
139-
errors.Add(errorLine);
140-
141-
if (token.IsCancellationRequested)
142-
{
143-
if (!Process.HasExited)
144-
Process.Kill();
145-
146-
Process.Close();
147-
onEnd?.Invoke();
148-
token.ThrowIfCancellationRequested();
149-
}
150-
151-
errorLine = errorStream.ReadLine();
152-
}
155+
if (token.IsCancellationRequested)
156+
Process.Kill();
157+
Process.Close();
158+
onEnd?.Invoke();
159+
token.ThrowIfCancellationRequested();
160+
}
153161

154-
if (Process.ExitCode != 0 && errors.Count > 0)
155-
{
156-
onError?.Invoke(null, string.Join(Environment.NewLine, errors.ToArray()));
157-
}
162+
if (Process.ExitCode != 0 && errors.Count > 0)
163+
{
164+
onError?.Invoke(null, string.Join(Environment.NewLine, errors.ToArray()));
158165
}
159166
}
160167

0 commit comments

Comments
 (0)