我已经写了周围的微软Office文档成像COM API的OCR包装库,并在一个控制台应用程序在本地运行,它完美的作品,每测试。

不幸的是,事情开始变得糟糕,当我们试图将其与WCF服务运行作为一个ASP.Net Web应用程序,IIS6下整合。我们有问题,周围试图腾出MODI COM对象,并有大量的可以帮助我们在网络上的例子。

然而,问题仍然存在。如果我重新启动IIS,并做web应用程序的部署新鲜,前几OCR尝试工作的伟大。如果我离开它30分钟左右,然后做另一个请求,我得到的服务器故障的错误是这样的:

  

在服务器引发异常。 (从HRESULT异常:0x80010105(RPC_E_SERVERFAULT)):在MODI.DocumentClass.Create(字符串的FileOpen)

从上,每个请求将失败做OCR,直到我重置IIS,并且循环再次开始。这一点

我们运行在它自己的应用程序池这个应用程序,并在具有本地管理员权限的身份运行。

更新:这个问题可以通过执行OCR东西了过程来解决。看来好像MODI库不使用托管代码打得好,当谈到自己后清理,因此产生新的流程,每个OCR请求我的情况运行良好。

下面是执行OCR功能:

    public class ImageReader : IDisposable
{
    private MODI.Document _document;
    private MODI.Images _images;
    private MODI.Image _image;
    private MODI.Layout _layout;
    private ManualResetEvent _completedOCR = new ManualResetEvent(false);

    // SNIP - Code removed for clarity

    private string PerformMODI(string fileName)
    {
        _document = new MODI.Document();
        _document.OnOCRProgress += new MODI._IDocumentEvents_OnOCRProgressEventHandler(_document_OnOCRProgress);
        _document.Create(fileName);

        _document.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true);
        _completedOCR.WaitOne(5000);
        _document.Save();
        _images = _document.Images;
        _image = (MODI.Image)_images[0];
        _layout = _image.Layout;
        string text = _layout.Text;
         _document.Close(false);
        return text;
    }

    void _document_OnOCRProgress(int Progress, ref bool Cancel)
    {
        if (Progress == 100)
        {
            _completedOCR.Set();
        }
    }
    private static void SetComObjectToNull(params object[] objects)
    {
        for (int i = 0; i < objects.Length; i++)
        {
            object o = objects[i];
            if (o != null)
            {
                Marshal.FinalReleaseComObject(o);
                o = null;
            }
        }
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public void Dispose()
    {
        SetComObjectToNull(_layout, _image, _images, _document);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

我然后实例化一个使用块内ImageReader的实例(其将调用IDisposable.Dispose上出口)

调用Marshal.FinalReleaseComObject应指示CLR释放COM对象,所以我不知所措弄清楚什么是导致我们出现上述症状。

有关它的价值,运行IIS以外的代码,比如在一个控制台应用程序,一切似乎防弹。它屡试不爽。

这是帮我诊断和解决这个问题将是一个巨大的帮助,我会给予好评像疯了似的任何提示! ; - )

谢谢!

有帮助吗?

解决方案

你有没有想过你的托管应用程序的OCR部分的外的过程的。

有一个服务可以给你吨的灵活性:

  1. 您可以定义为Web应用程序一个简单的终点,并通过远程处理或WCF访问它。
  2. 如果东西是梨形状和图书馆是所有道奇,你可以有服务推出的每一个需要进行OCR时单独的进程。这给你极致的安全性,但涉及一个小的额外费用。我假设的 OCR是远比旋转起来的过程更昂贵的即可。
  3. 您可以保留一个实例周围的COM对象的,如果内存泄漏开始,你可以重新开始自己,而不会影响网站(如果你很小心)。
  4. 我个人在过去发现COM互操作+ IIS =悲伤。

其他提示

MODI是非常靠不住的,当涉及到摆脱自身,在IIS中运行特别。根据我的经验,我发现,虽然它减缓都记录下来,只有这样,才能摆脱这些错误的是你的所以GC.Collect()调用后添加GC.WaitForPendingFinalizers()。如果你有兴趣,我写了一个这篇文章

您可以复制的问题,在一个小型控制台应用程序?也许离开它睡了30分钟,回来了吗?

为了解决这样的事情

最佳方法是将其完全分离下来。我很想看看它是如何工作。

我只好一个星期前处理这个错误,并测试了一些解决方案在这里发出后,我终于解决了这个问题。我做到了,我会在这里解释。

从HRESULT异常:

在我的情况下,我有一个窗口服务乳宁和处理文档从一个文件夹中,当存在多于20个文档,引发错误出现问题。0x80010105(RPC_E_SERVERFAULT)

在我的代码我是每次我检测该文件夹中的文档调用一个方法,我让MODI文档的实例(MODI.Document _document =新MODI.Document();)和i处理该文件,并且是什么原因导致的错误!!

解决方案是只有一个全球MODI.Document的实例,并处理所有的文件白衣它,这样我只有一个实例乳宁为我服务的所有时间。

我希望这将有助于那些谁是面临同样的问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top