AccessExceptionViolation, SEHException, and/or Procedure entry point not found in QBUtilities.dll when accessing QuickBooks from a WCF Service
我有一个由 WPF 应用程序调用的 WCF 服务(实际上是几个),全部在 .NET 4.0 下。使用 nsoftware 的 QuickBooks Integrator 5.0(QuickBooks SDK 的 .NET package库),我的大部分例程都可以正常工作。但是,当其中一些从新线程运行时,出现错误,特别是无法打开 QuickBooks 文件的错误,然后我会收到各种各样的奇怪错误,包括 SEHException,两者都是"invalid arg status util" 和 QBUtilities.dll 中的 "procedure entry point not found",以及访问异常冲突。
例如,当直接从客户端调用例程时,会按预期工作。假设我故意加载了错误的 QuickBooks 文件(意味着 QuickBooks 无法打开我的应用程序所期望的文件;一个致命的可捕获错误)并调用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | GetCustomerWithQB(int CustID) { .. set up code .. try { .. .. toReturn.QBCustomer.QBCustomer.Get(QuickBooksId); // this goes to QB to do the fetch } catch (nsoftware.InQB.InQBException x) { // we get, correctly, a 602"there is a different file open" error. } } |
但是,如果我从服务中调用该例程,则会产生一个新线程:
1 | Task.Factory.StartNew(delegate { GetCustomerWithQB(CustID); }); |
然后我得到了上面的各种错误。 GRRR。帮忙?
经过大量调试和一天的研究后,我发现我只有在同时调用两个例程时才遇到奇怪的错误。这导致我调查了许多途径,其中最有用的是这个问题。底线,我创建了一个静态单线程 StaTaskScheduler(来自 Microsoft 的 Parallel Extensions 库):
1 | _staSchedulerForQBCalls = new StaTaskScheduler(numberOfThreads:1); |
并将它用于调用 QuickBooks 的所有任务:
1 | Task.Factory.StartNew(delegate { GetCustomerWithQB(CustID); }, CancellationToken.None, TaskCreationOptions.None, _staSchedulerForQBCalls); |
正如这些事情通常所做的那样,事后看来这似乎相当明显,但奇怪的错误和有限的问题情况当然并没有在一开始就把我指向这个方向。