长时间运行的WCF服务阻止其他人

时间:2017-02-07 10:24:19

标签: c# asp.net wcf

我通过ServiceHost将InstanceContextMode设置为PerSession / PerCall

Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.PerSession;
Description.Behaviors.Find<ServiceBehaviorAttribute>().UseSynchronizationContext = false;
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior
{
    MaxConcurrentSessions = 1000,
    MaxConcurrentCalls = 1000,
    MaxConcurrentInstances = 1000
};
Description.Behaviors.Add(stb);

为每个调用创建新的服务实例。但是,据我所知,WCF服务使用ThreadPool中的线程,这些请求将排队到可用线程,直到它决定启动新线程。当存在长时间运行的服务时,它会阻止(某些?)后续请求被处理。

我甚至尝试将ThreadPool.SetMaxThreads()和ThreadPool.SetMinThreads()设置为高值,但仍然没有运气。

那么,处理这类问题有什么好处?

编辑:我尝试了PerSession / PerCall与ConcurrencyMode的不同组合,但它没有用。当我在IIS设置中提高数字或最大工作进程时它唯一的非阻塞

编辑了很长一段时间后:现在我明白不推荐在WCF服务中运行长时间运行的操作,因为它使用的是ThreadPool。由于一个阻塞请求将导致所有后续请求(自动排队到某个限制线程数量,直到ThreadPool决定它应该产生更多线程)。因此,我将其留给那些面临同样问题的人。

1 个答案:

答案 0 :(得分:1)

如果将InstanceContextMode.PerSession设置为InstanceContextMode,它会在客户端和服务应用程序之间建立新的通信会话时指示服务应用程序创建新的服务对象。 同一会话中的后续调用由同一个对象处理。

来自同一客户端的成功请求阻塞的主要原因是因为它与ConcurrencyMode有关,默认情况下为Single。这是什么意思?这意味着没有请求/调用可以中断正在进行的服务进程,因为它只使用单个线程来处理第一个请求,其他后续请求被阻塞或排队等待服务可用,如果第一个进程不是,它最终会超时还没完成。此外,服务不允许重入。

如果您想了解是否完全看到下面的链接,因为它相互影响。

InstanceMode and Concurrency Model