【问题标题】:Web API / WCF how keep object aliveWeb API / WCF 如何让对象保持活动状态
【发布时间】:2014-09-08 17:12:24
【问题描述】:

我有一个引擎(ABBYY FlexiCapture Engine),我想将它与 REST 服务(WebAPI 或 WCF)一起使用。 引擎启动初始化需要 30 秒。每个请求都太长了。我希望引擎加载服务启动并保持“预热”状态。 我如何使用 WebAPI 或 WCF 来做到这一点? (最好的方法是让线程与引擎保持活动状态)。 PS:对不起我的英语不好。

--来自 ABBYY 示例库

private void ProcessImages()
        {
            trace("Loading FlexiCapture Engine...");
            IEngine engine = LoadEngine();
            try
            {
                string samplesFolder = FceConfig.GetSamplesFolder();

                trace("Creating and configuring the FlexiCapture Processor...");
                IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();
                processor.AddDocumentDefinitionFile(samplesFolder + "\\SampleProject\\Templates\\Invoice_eng.fcdot");
                // ....

                trace("Adding images to process...");
                processor.AddImageFile(samplesFolder + "\\SampleImages\\Invoices_1.tif");
                // ....

                trace("Recognizing the images and exporting the results...");

                while (true)
                {
                    // Recognize next document
                    IDocument document = processor.RecognizeNextDocument();
                    // processing recognized document...
                }
            }
            finally
            {
                UnloadEngine(ref engine);
            }
        }

        private IEngine LoadEngine()
        {
            // FlexiCapture Engine can be loaded in three diffrent ways:
            // 1) Directly, as in this sample
            // 2) As an inproc server (using COM infrastructure)
            // 3) As an out-of-proc server in a worker process (using COM infrastructure)

            IEngine engine;
            int hResult = InitializeEngine(FceConfig.GetDeveloperSN(), null, null, out engine);
            Marshal.ThrowExceptionForHR(hResult);
            return engine;
        }

我想创建引擎。之后,我将创建和配置几个 FlexiCapture 处理器。 (需要很长时间,我想在服务启动时进行) 比,当用户添加图像时 - 我将使用其中一个处理器来识别它们。

启动时: 创建引擎 -> 创建几个处理器(+配置它们); 在方法调用上: 使用一个免费的处理器 -> 识别用户图像。

【问题讨论】:

  • 你能贴出管理引擎生命周期的代码吗?

标签: c# wcf asp.net-web-api


【解决方案1】:

也许,您需要实现引擎的静态单例实例并使用上下文

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public static class EngineContainer
{
    private static Engine _engine { get; set; }
    public static Engine GetEngine 
    {
        get { if (_engine == null) Init(); return _engine; }
    }
}

【讨论】:

  • 虽然这可能可行,但除非绝对必要,否则不建议使用单例服务实例,因为它们无法扩展
  • @Tom Redfern:高初始化成本是实现 SingleInstance 模式的完全正当理由。实际上,这很可能是这样做的唯一正当理由:)
  • @JohannBlais 我同意你的观点,高初始化成本是使用单例的正当理由。我要说的是,你最好确定情况确实如此。当前描述的 OP 问题听起来不像是不可避免的预热成本之一,而是生命周期管理问题,即为每个服务请求创建一个外部资源堆栈的新实例。
  • 在这种情况下什么会更好 - 使用 WCF + REST 或 WebAPI?
  • WCF + REST 让您可以更好地控制设置
【解决方案2】:

如果您的引擎没有任何用户界面 (UI),那么您可以使用带有 WCF(自托管)的 Windows 服务。让 Windows 服务处理您的引擎(即活动对象)并通过 WCF 服务处理用户请求

【讨论】:

  • 服务必须托管在 IIS 上。是的,引擎没有任何用户界面。
  • 为什么你更喜欢只在 IIS 中托管?
  • 这不会解决 OP 的问题。
猜你喜欢
  • 1970-01-01
  • 2020-08-12
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多