이 코드는 deadlock condition에 대해 읽었습니다.이 코드는 내 코드 (아래)에 영향을줍니다. 이 코드는 지난 12 년 동안 Windows Server 2003 (.net 2.0)에서 완벽하게 작동했습니다. 이제는 항상 교착 상태가있는 Windows Server 2012로이 서버를 이동하려고했습니다.프로세스 제거 .WaitForExit()/StandardOutput 교착 상태
내 DLL은 "anyCPU"(여전히 .net 2.0을 대상으로 함)로 빌드되지만 실행되는 실행 프로세스는 절대적으로 32 비트이며 Server 2003에서 Server 2012 로의 이동은 32 비트에서 64 비트로 이동합니다. bit OS.
문제를 해결하기 위해해야 할 일이 무엇인지 이해하고 있지만이 동작이 Server 2003에서 Server 2012로 변경된 이유를 알고있는 사람이 있습니까?
public string DoMyProcess(string filenameAndPath, string arguments)
{
string stdout="";
int exitCode = 0;
try
{
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.FileName = filenameAndPath;
procStartInfo.CreateNoWindow = true;
procStartInfo.Arguments = arguments;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
System.Diagnostics.Process theProcess = null;
try
{
theProcess = Process.Start(procStartInfo);
theProcess.WaitForExit();
exitCode = theProcess.ExitCode;
// moving this ABOVE WaitForExit should eliminate deadlocks
// But why did it always work on Server 2003 but not on Server 2012?
stdout = theProcess.StandardOutput.ReadToEnd();
}
catch (System.Exception e)
{
string errMsg = e.Message;
log_the_error("threw an exception: " + e.Message);
}
}
return stdout;
}
UPDATE :
try
{
theProcess = Process.Start(procStartInfo);
stdout = theProcess.StandardOutput.ReadToEnd();
}
catch (System.Exception e)
{
string errMsg = e.Message;
log_the_error("threw an exception: " + e.Message);
}
}
어떤 다른 조건이 교착 상태가 발생할 수 있습니다 : 아직 심지어 권장하는 위의 코드를 변경 한 후, 존재
미스터리 교착? 만약 내가 StandardError를 검사한다면, 유용한 것을 알려줄 수 있을까요?
업데이트 # 2 :
FWIW, 우리는 프로비저닝 만 가끔이 코드는 12 년에 실행 된 원래의 시스템 구성했다 IIS 6 (실행하는 다른 Windows Server 2003 (32 비트) 이중 자물쇠). 서버 2012에서 교착 상태가되는 동일한 코드는이 서버 2003에서 취소되지 않습니다.
이제 우리는이 문제를 재현하는 최소한의 완전한 코드를 갖게되었습니다. 그러나 우리가 라이센스 한 .exe에는 프로세스가 실행 중이므로 게시를 막는 기밀 조항이 있습니다. 전문가가 여기에 도움이되지 않는다는 것을 알고 있습니다.
우리가 만난 한가지 힌트는 실제 서버에 설치된 Visual Studio 2013 디버거를 통해 실행될 때 프로세스가 교착 상태가 발생하거나 멈추지 않고 서버 외부의 브라우저에서 프로세스를 호출하는 것입니다. 이상하게도 - 2012 년 서버의 브라우저에서 해당 테스트 페이지에 연결할 수 없습니다. 브라우저는 "연결"하고 결국 타임 아웃합니다 (그러나 동일한 서버에서 호스팅되는 다른 사이트/동일한 IIS 8에 도달 할 수 있음).)
관리 명령 셸 또는 관리자가 아닌 명령 셸에서 수동으로 실행하는 명령 줄 매개 변수가 완벽하게 작동하기 때문에이 명령 줄에서 64 비트/WOW64 문제라고 생각하기 어렵습니다 32 비트 실행 파일이거나 필수 DLL입니다. 우리는 권한이 문제를 일으킬 수있는 장소를 계속 검색합니다 (프로세스는 temp 폴더에 작성해야합니다. 임시 폴더는 지금은 c : \ temp에 배치했습니다).
잘못된 코드 패턴이 인터넷에 널리 퍼져 있지만, [Process.OutputDataReceived Event] (https://msdn.microsoft.com/en-us/library/system.diagnostics)에서 제공하는 MS 예제를 사용해보십시오. .process.outputdatareceived (v = vs.110) .aspx? cs-save-lang = 1 & cs-lang = csharp # code-snippet-2)를 시작점으로 사용합니다. 해당 이벤트와 다른 프로세스 이벤트가 보조 스레드에 도착 했으므로 적절하게 계획을 세우십시오. – TnTinMn
re : 편집 한 업데이트, 교착 상태를 유발할 수있는 코드가 코드에 남아 있지 않습니다. 그렇다고해서 ... [mcve]를 제공하지 않았기 때문에 여기서 다른 코드가 무엇인지 알 수는 없습니다. 'StandardError'를 읽는 것은 유용 할 수도 있고 그렇지 않을 수도 있습니다; 교착 상태로 외부 프로세스에서 어떤 종류의 오류 또는 사용자 프롬프트를 잘못 해석 할 수 있습니다. 실제로는 사용자 또는 다른 사람이 응답하기를 기다리고있을 때입니다. 'StandardError'를 _do_ 리다이렉트하면, 데드락의 가능성을 소개하고이를 피하는 지 확인하고 싶을 것이다. –
나는 여기에있는 질문과 다른 질문에 대답하면서 코드를 교착 상태없이 'StandardOutput'과'StandardError' 둘 모두를 리디렉션하는 예제를 포함하는 몇 가지 다른 대답을 갖고 있습니다. 그 중 하나 이상이 유용 할 수 있습니다. http://stackoverflow.com/a/33508142, http://stackoverflow.com/a/26722542 및 http://stackoverflow.com/a/38881345 –