asp.net - 如何在 ASP.Net Web 应用程序中使用 MODI?

标签 asp.net ocr modi

我已经围绕 Microsoft Office Document Imaging COM API 编写了一个 OCR 包装器库,并且在本地运行的控制台应用程序中,它在每次测试中都能完美运行。

遗憾的是,当我们尝试将其与在 IIS6 下作为 ASP.Net Web 应用程序运行的 WCF 服务集成时,事情开始变得糟糕。我们在尝试释放 MODI COM 对象时遇到了问题,网络上有很多示例可以帮助我们。

但是,问题仍然存在。如果我重新启动 IIS,并重新部署 Web 应用程序,前几次 OCR 尝试效果很好。如果我将其保留 30 分钟左右,然后执行另一个请求,我会收到如下服务器故障错误:

The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)): at MODI.DocumentClass.Create(String 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();
    }
}

然后,我在 using block 内实例化 ImageReader 的实例(退出时将调用 IDisposable.Dispose)

调用 Marshal.FinalReleaseComObject 应该指示 CLR 释放 COM 对象,因此我不知道是什么导致了我们所遇到的症状。

就其值(value)而言,在 IIS 之外运行此代码(例如在控制台应用程序中),一切似乎都是无懈可击的。每次都有效。

任何帮助我诊断和解决这个问题的提示都将是一个巨大的帮助,我会疯狂地投票! ;-)

谢谢!

最佳答案

您是否考虑过进程外托管应用的 OCR 部分。

拥有服务可以为您带来巨大的灵 active :

  1. 您可以为 Web 应用程序定义一个简单的端点,并通过远程处理或 WCF 访问它。
  2. 如果东西是梨形的,并且库都是闪避的,那么您可以让该服务在每次需要执行 OCR 时启动一个单独的进程。这为您提供了极大的安全性,但会产生少量的额外费用。我认为OCR 比启动流程要昂贵得多
  3. 您可以保留 COM 对象的实例,如果内存开始泄漏,您可以自行重新启动而不影响网站(如果您小心的话)。

我个人过去发现 COM 互操作 + IIS = 悲伤。

关于asp.net - 如何在 ASP.Net Web 应用程序中使用 MODI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1344510/

相关文章:

javascript - 当用户按下文本框中的某个键时运行代码

asp.net - 更新命令在动态数据详细信息 View 中不起作用

c# - ASP.net上传文件,如果存在则重命名

asp.net - UrlRewriting 在服务器上不起作用,但在本地主机上它在 asp.net 上工作正常?

javascript - 将 OCRed 非结构化文本转换为正确的文本

c# - Windows 7 光学识别 API

python - OpenCV Python : find contours/edges/rectangle in an image

ocr - 大写字母的常见 OCR 错误有哪些?

ocr - 土耳其语版 Tesseract OCR 多维数据集文件

vbscript - 如何让 MODI 不识别旋转图像?