问题
I've a following up question to What is the stack size of a BackgroundWorker DoWork Thread? Is there way to change it?
Should I increase the stack size of my main program using the following post build event:
"$(DevEnvDir)..\..\VC\bin\editbin.exe" /STACK:8388608 "$(TargetPath)"
or should I capsule my recursive code block inside a new thread with a larger stack size?
Thread thread = new Thread(delegate()
{
// do work with larger stack size
}, 8192 * 1024);
thread.Start();
thread.Join();
The code which has a lot of recursion is from Intel MKLs the LAPACKE_dtrtri function which I call over DLLImport
. So I cannot change this code. I can just change the stack size to avoid a stack overflow error.
What is the draw back of assign a larger stack size to my main program?
What is the draw back of creating a new thread with a larger stack size for this calculation?
Which solution is the better one?
What would be a reasonable stack size? 8 MB, 16 MB, 32 MB or 64 MB (like MATLAB)? The program runs on computers which have at least 16 GB of RAM (up to 256 GB).
Note: for 99% of my application the default stack size of 4 MB (64-bit) would be enough but the other 1% is using external code which is heavily recursive.
回答1:
- Which solution is the better one?
- Which solution is the better one?
The first approach using editbin
in a post-build event is failing when using strong name key to sign the assembly. After the assembly was changed using editbin
the verification of the signed assembly will fail. sn.exe -v assembly.exe
will return Failed to verify assembly -- Strong name validation failed ...
See as well:
- Is an assembly signed with a strong name before or after the post-build event?
Using the AfterCompile
event and resigning the assembly is a workaround (which I'm using now). The project file should contain the following lines:
<Target Name="AfterCompile">
<Exec Command="
"$(DevEnvDir)..\..\VC\bin\editbin.exe" /STACK:16777216 "$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)"
"$(FrameworkSDKDir)bin\NETFX 4.5.1 Tools\sn.exe" -Ra "$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)" "$(SolutionDir)\STRONGNAME.snk"
" />
</Target>
<PropertyGroup>
<PostBuildEvent>REM "See AfterCompile for stack size and resigning"</PostBuildEvent>
</PropertyGroup>
I was getting aware of the after compile event when I was reading the following answer: https://stackoverflow.com/a/22617361/7556646
The second approach but for the hole program and not only for the recursive code blocks would look like that:
static class Program
{
[STAThread]
static void Main(string[] args)
{
Thread thread = new Thread(delegate()
{
Main2(args);
}, 16 * 1024 * 1024);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
static void Main2(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(app);
}
}
The second approach has the drawback that the stack size of a BackgroundWorker DoWork event is still 1 MB (32-bit or any) or 4 MB (64-bit).
See as well:
- What is the stack size of a BackgroundWorker DoWork Thread? Is there way to change it?
- What is the draw back of creating a new thread with a larger stack size for this calculation?
- What would be a reasonable stack size?
See the comments from Hans Passant.
来源:https://stackoverflow.com/questions/56476465/increase-stack-size-of-main-program-or-create-a-new-thread-with-larger-stack-siz