我们目前有多个使用默认ServiceBehavior
的WCF服务。由于可伸缩性问题,我们正在考虑应用ConcurrencyMode = ConcurrencyMode.Multiple
属性来提高吞吐量。我们所有的服务电话都是无国籍的,例如:
PersonService.cs:
public class PersonService : IPersonService
{
public GetPersonResponse GetPerson(GetPersonRequest request)
{
GetPersonResponse response = new GetPersonResponse();
try
{
response.Person = Person.GetPerson(request.PersonID);
return response;
}
catch (Exception ex)
{
return (GetPersonResponse) response.SetException(ex);
}
}
}
Person.cs:
public static class Person
{
public static PersonDataContract GetPerson(int personID)
{
PersonDataContract pdc = null;
// load contract from db...
pdc = Database.Load<PersonDataContract>(personID);
// Address is another static class in the same pattern as Person
pdc.Addresses = Address.GetAddressesForPerson(personID);
return pdc;
}
}
Person
类中的所有方法都是静态的,以帮助提高性能,而无状态的线程安全性。 Database
类也是静态的,但其方法引用静态变量。
在这种情况下,为了使ConcurrencyMode.Multiple
不导致多线程问题,需要为线程安全做些什么?我只考虑Database
类,但是Person
类(以及遵循相同模式的所有其他类)是否也需要锁定?
我知道所有类应该是防弹的,以确保最大的安全性,但遗憾的是时间限制不允许这样做...我们需要尽快获得代码。
答案 0 :(得分:4)
如果您使用默认的“每次调用”激活机制(如果您的服务完全无状态,那么它很有效),添加ConcurrencyMode.Multiple
绝对没有意义,因为每个传入的请求都会获得自己的服务实例用于处理其请求的类。这是InstanceContextMode
的首选和推荐设置。
在MSDN杂志上阅读有关WCF中实例管理的更多信息:Discover Mighty Instance Management Techniques For Developing WCF Apps
当您使用ConcurrencyMode.Multiple
时,唯一的好处就是当您拥有单一的WCF服务时 - 但这是非常气馁的,因为它是a)可扩展性的一大障碍,以及b)正确编程非常棘手。
我的建议是:尝试更详细地缩小范围 确实导致性能问题。只是跳进ConcurrencyMode.Multiple
似乎是错误的方法 - 它非常混乱,非常耗费人力,代码很多,很有可能弄错......
答案 1 :(得分:2)
如果您的服务是无状态且线程安全的,最好将InstanceContextMode.Single与ConcurrencyMode.Multiple结合使用。
这将避免创建服务实例,减少内存占用,减少GC活动。
我开发的几乎所有服务都是以这种方式完成的......
除非需要为每次通话或会话保留单独的实例,否则我会按照他的方式进行。
其他答案提及&#34;单身WCF服务 - 但这是非常气馁的,因为它是a)可扩展性的一大障碍,b)正确编程非常棘手。&#34;
不是非常气馁,对可扩展性没有影响(事实上可能是有益的),并且没有任何棘手的问题。