从WebAPI项目运行静态类时的StackOverflow异常 - 从控制台应用程序运行时工作正常

时间:2017-04-12 13:22:48

标签: c# c++ asp.net-web-api thread-safety appdomain

我有一个包装C ++ DLL的第三方库 - 让我们称之为LegacyAPI。这个包装库是一个带有导入方法的静态类,不是线程安全的。

我有自己的包装器库,它包装了第三方包装器(提供日志记录等)。我们称之为LegacyAPIWrapper

所以,这一切都应该在网络API中使用 - 让我们称之为WebAPI

我的WebAPI控制器操作会调用我的LegacyAPIWrapper。它经历了一些方法(包括对不安全LegacyAPI的调用),并且在StackOverflow异常时失败 - 始终使用LegacyAPI中的相同方法。

要解决这个问题,我创建了一个控制台应用程序 - ConsoleApp。它调用我的LegacyAPIWrapper的方式与WebAPI的调用方式相同 - 而且运行正常!

我已在我的web api控制器方法上强制执行STA Thread,如此处所述。 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初始化到抛出错误的位置,我们在同一个Thread中是一致的,它是一个STA,它是一个正在运行的线程。

除此之外,我还尝试按照此处的建议在单独的AppDomain中调用LegacyAPIWrapper

https://bitlush.com/blog/executing-code-in-a-separate-application-domain-using-c-sharp

但它没有改变任何东西。并且,通过“任何事情”,我也意味着我们仍然在同一个线程上(在隔离被调用之前和隔离之内) - 所以也许我做错了什么?

任何提示都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

我已经解决了'它 - 它证明了这是第三方应用程序的堆栈大小要求的问题。

当在w3wp进程上托管时,可用的堆栈太小 - 这就是它作为控制台应用程序托管时的原因。

w3wp.exe堆栈大小为256kb(以前是2003年之前的1MB)

https://blogs.msdn.microsoft.com/tom/2008/03/31/stack-sizes-in-iis-affects-asp-net/

决议

  1. 在文件资源管理器中,浏览到C:\ Windows \ SysWOW64 \ inetsrv \
  2. 右键单击w3wp.exe并选择Properties>安全>高级>所有者>编辑>将所有者更改为>管理员>好的>好的>行
  3. 授予[Admin-User] w3wp.exe
  4. 的完全权限
  5. 按Windows工具栏上的“开始”按钮,然后在“搜索程序和文件”中,键入“cmd”
  6. 右键单击cmd.exe并选择“以管理员身份运行”
  7. 键入:" C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC \ vcvarsall.bat“
  8. 类型:cd C:\ Windows \ SysWOW64 \ inetsrv
  9. 类型:EDITBIN / STACK:1048576 w3wp.exe