.net - 在 IIS 中托管的 WCF 服务中使用非托管线程不安全库

标签 .net wcf iis thread-safety unmanaged

我在 IIS 中托管了一个 WCF 服务,该服务调用线程不安全的非托管库。

我需要以某种方式设置 IIS,以便它保留一个进程池并为每个进程分配一个请求。

我该怎么做?

线程不安全的本质解释: 非托管库包含进程范围的共享静态数组,该数组在操作开始时归零,然后在操作过程中缓慢(30s-3m)填充结果,然后最终结果返回给我。调用不是 CPU 密集型的,数据是从外部来源收集的。 进行顺序调用是安全的,但任何并行调用都会导致数组中的数据损坏,并且两个调用都会返回错误的结果。 我无法控制这个库。

我需要能够并行处理 30-100 个请求。

最佳答案

由于您有一个单一的进程资源,您将需要手动启动进程,因为我不知道有什么方法可以自动执行此操作。您仍然可以使用 WCF 执行进程间通信,并为所有进程提供一个面向公众的入口点。

您需要一个主管服务来接受请求、启动工作进程、向其发送数据并等待其完成,然后接收数据并将其转发给原始请求者。每个工作进程都可以使用 ServiceHost 托管一个 WCF 服务器。类(使用起来非常简单)。您可以让工作进程在返回结果时终止,也可以执行您自己的池。如果你想汇集,只需在 worker 契约(Contract)上有两种方法:DoWorkShutdown .连续调用每个工作人员的 DoWork,或者您可以通过将以下属性应用于工作人员服务类,让 WCF 本身阻止并发请求:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
                 ConcurrencyMode = ConcurrencyMode.Single)]

这将确保任何在单个工作进程上运行两个并行操作的尝试都会阻塞请求并将请求排队,因此您可以简单地以循环方式调用所有工作线程来处理和排队峰值负载超出您的处理能力。

您的主管将有一个简单的面向客户的契约(Contract),该契约(Contract)只是将工作分配给工作流程。如果您正在集中工作人员,则可以在负载减少并且不再需要他们时关闭其中一些工作人员(如果需要的话)。主管可以使用 WCF 的异步模式来使用几乎不使用任何资源(因为它实际上不做任何工作),而不是每个请求都阻塞并占用一个线程。对于 WCF 异步,我建议使用 .NET 4.5,因为与跳过 .NET 4.0 及更低版本中 WCF 所需的异步循环相比,它更容易实现(只需返回 Task<T>)。

最重要的是,由于您的奇怪限制,您将不得不做一些腿部锻炼才能实现您想要的目标。尽管如此,大部分管道仍然可以由 WCF 处理。

关于.net - 在 IIS 中托管的 WCF 服务中使用非托管线程不安全库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14096940/

相关文章:

c# - 在 Log4Net 中找不到 Logger 时设置默认日志

.net - 具有 C# 7 模式匹配的 Expression.SwitchCase

android - 使用 WCF REST 将数据从服务器推送到 android 应用程序

c# - Application_BeginRequest 未在生产服务器上为 JPG 触发

asp.net - Tortoise SVN 操作后文件丢失 IIS_IUSRS 权限

c# - 如何处理 OdbcException

wcf - System.ServiceModel.Security.SecurityNegotiationException : Could not establish trust relationship for the SSL/TLS secure channel with authority

c# - yield return 是否跨服务边界工作?

php - 在 IIS 上托管 Wordpress 时建立数据库连接时出错

c# - 将类型转换为通用类定义