当来自 WebAPI 项目的 运行ning static class 时发生 StackOverflow 异常 - 当来自控制台应用程序的 运行 时工作正常
StackOverflow exception when running static class from a WebAPI project - works fine when run from a console application
我有一个包装 C++ dll 的第 3 方库 - 我们称它为 LegacyAPI
。这个包装库是静态的 class,带有导入的方法,不是线程安全的。
我有自己的包装器库,用于包装这个第 3 方包装器(以提供日志记录等)。我们称它为 LegacyAPIWrapper
所以,这一切都应该在网络中使用 api - 让我们称之为 WebAPI
我的 WebAPI
控制器操作调用我的 LegacyAPIWrapper
。它通过一些方法(包括调用不安全的 LegacyAPI
),并因 Whosebug 异常而失败 - 始终使用来自 LegacyAPI
.
的相同方法
为了解决这个问题,我创建了一个控制台应用程序 - ConsoleApp
。它调用我的 LegacyAPIWrapper
的方式与 WebAPI
调用的方式相同 - 而且它工作正常!
我已按照此处所述在我的网络 api 控制器方法上强制执行 STA 线程。
http://ryanhaugh.com/archive/2014/05/24/supporting-sta-threads-in-web-api/
此外,包装器方法也具有 STAThread 属性。
我引入了一些额外的日志记录逻辑
this.Logger.Debug($"Apartment state: [{Thread.CurrentThread.GetApartmentState()}]. Thread ID: [{Thread.CurrentThread.ManagedThreadId}]. Thread State: [{Thread.CurrentThread.ThreadState}]");
这表明从初始化 LegacyAPIWrapper 的地方到它抛出错误的地方,我们始终在同一个线程中,它是一个 STA 并且它是一个 运行 线程。
除此之外,我还尝试按照此处的建议在单独的 AppDomain 中调用 LegacyAPIWrapper
https://bitlush.com/blog/executing-code-in-a-separate-application-domain-using-c-sharp
但它并没有改变任何东西。而且,'anything',我的意思是我们仍然在同一个线程上(在调用 Isolated 之前和在 Isolated 内)——所以也许我做错了什么?
如有任何提示,我们将不胜感激。
我有 'solved' - 结果证明这是第 3 方应用程序的堆栈大小要求的问题。
在 w3wp 进程上托管时,可用堆栈太小 - 这就是它在作为控制台应用程序托管时起作用的原因。
w3wp.exe 堆栈大小为 256kb(2003 年之前为 1MB)
https://blogs.msdn.microsoft.com/tom/2008/03/31/stack-sizes-in-iis-affects-asp-net/
分辨率
- 在文件资源管理器中,浏览到 C:\Windows\SysWOW64\inetsrv\
- 右键单击 w3wp.exe 和 select 属性 > 安全 > 高级 > 所有者 > 编辑 > 将所有者更改为 > 管理员 > 确定 > 确定 > 确定
- 授予 [Admin-User] 对 w3wp.exe
的完全权限
- 按 Windows 工具栏上的“开始”按钮,然后在“搜索程序和文件”中键入“cmd”
- 右键单击 cmd.exe 和 select“运行 以管理员身份”
- 类型:“C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”
- 类型:cd C:\Windows\SysWOW64\inetsrv
- 类型:EDITBIN /STACK:1048576 w3wp.exe
我有一个包装 C++ dll 的第 3 方库 - 我们称它为 LegacyAPI
。这个包装库是静态的 class,带有导入的方法,不是线程安全的。
我有自己的包装器库,用于包装这个第 3 方包装器(以提供日志记录等)。我们称它为 LegacyAPIWrapper
所以,这一切都应该在网络中使用 api - 让我们称之为 WebAPI
我的 WebAPI
控制器操作调用我的 LegacyAPIWrapper
。它通过一些方法(包括调用不安全的 LegacyAPI
),并因 Whosebug 异常而失败 - 始终使用来自 LegacyAPI
.
为了解决这个问题,我创建了一个控制台应用程序 - ConsoleApp
。它调用我的 LegacyAPIWrapper
的方式与 WebAPI
调用的方式相同 - 而且它工作正常!
我已按照此处所述在我的网络 api 控制器方法上强制执行 STA 线程。 http://ryanhaugh.com/archive/2014/05/24/supporting-sta-threads-in-web-api/ 此外,包装器方法也具有 STAThread 属性。
我引入了一些额外的日志记录逻辑
this.Logger.Debug($"Apartment state: [{Thread.CurrentThread.GetApartmentState()}]. Thread ID: [{Thread.CurrentThread.ManagedThreadId}]. Thread State: [{Thread.CurrentThread.ThreadState}]");
这表明从初始化 LegacyAPIWrapper 的地方到它抛出错误的地方,我们始终在同一个线程中,它是一个 STA 并且它是一个 运行 线程。
除此之外,我还尝试按照此处的建议在单独的 AppDomain 中调用 LegacyAPIWrapper
https://bitlush.com/blog/executing-code-in-a-separate-application-domain-using-c-sharp
但它并没有改变任何东西。而且,'anything',我的意思是我们仍然在同一个线程上(在调用 Isolated 之前和在 Isolated 内)——所以也许我做错了什么?
如有任何提示,我们将不胜感激。
我有 'solved' - 结果证明这是第 3 方应用程序的堆栈大小要求的问题。
在 w3wp 进程上托管时,可用堆栈太小 - 这就是它在作为控制台应用程序托管时起作用的原因。
w3wp.exe 堆栈大小为 256kb(2003 年之前为 1MB)
https://blogs.msdn.microsoft.com/tom/2008/03/31/stack-sizes-in-iis-affects-asp-net/
分辨率
- 在文件资源管理器中,浏览到 C:\Windows\SysWOW64\inetsrv\
- 右键单击 w3wp.exe 和 select 属性 > 安全 > 高级 > 所有者 > 编辑 > 将所有者更改为 > 管理员 > 确定 > 确定 > 确定
- 授予 [Admin-User] 对 w3wp.exe 的完全权限
- 按 Windows 工具栏上的“开始”按钮,然后在“搜索程序和文件”中键入“cmd”
- 右键单击 cmd.exe 和 select“运行 以管理员身份”
- 类型:“C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”
- 类型:cd C:\Windows\SysWOW64\inetsrv
- 类型:EDITBIN /STACK:1048576 w3wp.exe