gpt4 book ai didi

c# - 为什么在具有两个进程和输出重定向的代码中没有捕获到 ThreadAbortException?

转载 作者:太空宇宙 更新时间:2023-11-03 20:08:06 28 4
gpt4 key购买 nike

下面的代码仅用于说明问题。请忽略使用 CodeDom 编译源代码的部分。此外,如果您尝试它,它会使“其他进程”可执行文件继续运行并无益地消耗 CPU 时间。

真正的问题是我启动线程,然后中止线程并看到“Thread abort initiated”消息并且有

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll

调试器输出中的消息,但 catchfinally block 均未被调用,并且这些 block 没有输出。

当然,因为为处理重定向输出而创建的额外线程没有中止,所以程序永远挂起,但是...

为什么 catchfinally 没有被调用?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
new Program().payload();
}

private void payload()
{
var otherExecutableName = "OtherProcess.exe";
compileOtherProcessExecutable(otherExecutableName);
var thread = new System.Threading.Thread(() => threadFunc(otherExecutableName));
thread.Start();
Thread.Sleep( 1000 );
thread.Abort();
Debug.WriteLine("Thread abort initiated");
}

private void threadFunc( String secondExecutableName )
{
Process process = null;
try {
process = new Process();
{
process.StartInfo.FileName = secondExecutableName;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;

process.OutputDataReceived += new DataReceivedEventHandler(outputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(outputHandler);

process.Start();

process.BeginOutputReadLine();
process.BeginErrorReadLine();

process.WaitForExit();
}
} catch( Exception e ) {
Debug.WriteLine( "Catch block: " + e.Message );
} finally {
Debug.WriteLine( "Finally block" );
if( process != null ) {
process.Kill();
Debug.WriteLine( "Process killed" );
}
}
}

static void compileOtherProcessExecutable(string filePath)
{
using (var compiler = new CSharpCodeProvider())
{
var parameters = new CompilerParameters(null, filePath, true);
parameters.GenerateExecutable = true;
var compResult = compiler.CompileAssemblyFromSource( parameters, otherProcessCode);
var errs = compResult.Errors;
if (errs.HasErrors)
{
var err = errs.Cast<CompilerError>().First();
throw new InvalidOperationException(String.Format(
"Compilation failed. Line {0}: {1}", err.Line, err.ErrorText));
}
}
}

private void outputHandler(object process, DataReceivedEventArgs output)
{
}

static readonly String otherProcessCode =
@"class Program {
public static void Main(string[] args)
{
while( true ) {
}
}
}";
}
}

最佳答案

问题是 WaitForExit 调用。此托管调用最终将在 native 框架中触底。当线程处于 native 代码中时发生 Abort 调用时,在线程返回到托管代码之前什么都不会发生。在这种情况下,线程正在等待进程完成,因此在您实际终止进程之前不会真正返回

注意:即使抛出异常,catch block 也不会真正捕获它。异常将在 block 的末尾重新抛出。您需要捕获它并调用 ResetAbort 方法

关于c# - 为什么在具有两个进程和输出重定向的代码中没有捕获到 ThreadAbortException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21734106/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com