问题描述
我知道 C# 主程序的堆栈大小为 1 MB(32 位和任何)或 4 MB(64 位),请参阅 为什么 C# 中的堆栈大小正好是 1 MB?
I know for a C# main program the stack size 1 MB (32-bit and any) or 4 MB (64-bit), see Why is stack size in C# exactly 1 MB?
BackgroundWorker
DoWork
线程的默认堆栈大小是多少?
What is the default stack size of the BackgroundWorker
DoWork
thread?
有没有办法改变BackgroundWorker
DoWork
线程的堆栈大小,同时创建另一个线程,如下例所示:
Is there a way to change the stack size of the BackgroundWorker
DoWork
thread beside creating another thread like the following example:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Thread thread = new Thread(delegate()
{
// do work with larger stack size
}, 8192 * 1024);
thread.Start();
thread.Join();
}
我使用 BackgroundWorker
是因为我有一个 Windows Forms
应用程序,我在其中在 DoWork
事件中进行了一些计算.我这样做是因为我想向 GUI 的状态行报告,并且我希望用户可以取消计算.
I'm using a BackgroundWorker
because I've a Windows Forms
application where I do some calculations inside the DoWork
event. I'm doing it this way because I want to report back to the status line of the GUI and I want the possibility that user can cancel the calculations.
我收到堆栈溢出错误,因为我正在调用英特尔 MKL LAPACKE_dtrtri 这是大量递归的,参见 http://www.netlib.org/lapack/explore-html/df/d5c/lapacke__dtrtri_8c_source.html.
I'm getting a stack overflow error because I'm calling Intel MKLs LAPACKE_dtrtri which is heavily recursive, see http://www.netlib.org/lapack/explore-html/df/d5c/lapacke__dtrtri_8c_source.html.
以下代码显示了我如何调用英特尔 MKL:
The following code shows how I call Intel MKL:
public static double[,] InvTriangularMatrix(double[,] a, bool isupper)
{
int n1 = a.GetLength(0);
int n2 = a.GetLength(1);
if (n1 != n2) throw new System.Exception("Matrix must be square");
double[,] b = Copy(a);
int matrix_layout = 101; // row-major arrays
char uplo = isupper ? 'U' : 'L';
char diag = 'N';
int lda = Math.Max(1, n1);
int info = _mkl.LAPACKE_dtrtri(matrix_layout, uplo, diag, n1, b, lda);
if (info > 0) throw new System.Exception("The " + info + "-th diagonal element of A is zero, A is singular, and the inversion could not be completed");
if (info < 0) throw new System.Exception("Parameter " + (-info) + " had an illegal value");
return b;
}
和
[DllImport(DLLName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
internal static extern int LAPACKE_dtrtri(
int matrix_layout, char uplo, char diag, lapack_int n, [In, Out] double[,] a, int lda);
InvTriangularMatrix
在我的 DoWork
事件中被调用.当我没有设置堆栈大小时,我在 LAPACKE_dtrtri
函数中收到堆栈溢出错误.
The InvTriangularMatrix
is called inside my DoWork
event. When I'm not setting the stack size I'm getting a stack overflow error inside the LAPACKE_dtrtri
function.
矩阵的大小可以从 1000 x 1000 到 100000 x 100000.如果矩阵大于 65535 x 65535,请参阅 超过 65535^2 个元素的二维数组 -->数组维度超出支持范围.
The size of matrix can be in the order of 1000 x 1000 up to 100000 x 100000. If the matrix is larger than 65535 x 65535 see 2d-Array with more than 65535^2 elements --> Array dimensions exceeded supported range.
推荐答案
BackgroundWorker
DoWork
事件内的堆栈大小与主线程相同.
The stack size inside a BackgroundWorker
DoWork
event is the same as for the main thread.
教授:
将构建后事件中的堆栈大小设置为 8 MB,例如:
Set the stack size in a post build event to 8 MB for example:
"$(DevEnvDir)....VCineditbin.exe" /STACK:8388608 "$(TargetPath)"
然后使用以下代码询问堆栈大小:
Then ask for the stack size using the following code:
[DllImport("kernel32.dll")]
internal static extern void GetCurrentThreadStackLimits(out uint lowLimit, out uint highLimit);
public static uint GetStackSize()
{
uint low, high;
GetCurrentThreadStackLimits(out low, out high);
return high - low;
}
在主程序和 DoWork
事件中使用 GetStackSize
返回 8 MB 或您使用 EDITBIN/STACK
指定的任何内容.
Using GetStackSize
in the main program and in the DoWork
event return in both cases 8 MB or whatever you specified using EDITBIN /STACK
.
这篇关于BackgroundWorker DoWork 线程的堆栈大小是多少?有没有办法改变它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!