我有一个包装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
但它没有改变任何东西。并且,通过“任何事情”,我也意味着我们仍然在同一个线程上(在隔离被调用之前和隔离之内) - 所以也许我做错了什么?
任何提示都将受到赞赏。
答案 0 :(得分:0)
我已经解决了'它 - 它证明了这是第三方应用程序的堆栈大小要求的问题。
当在w3wp进程上托管时,可用的堆栈太小 - 这就是它作为控制台应用程序托管时的原因。
w3wp.exe堆栈大小为256kb(以前是2003年之前的1MB)
https://blogs.msdn.microsoft.com/tom/2008/03/31/stack-sizes-in-iis-affects-asp-net/
决议