Windows服务/ WCF和线程,初学者提问

时间:2010-11-18 15:20:06

标签: c# multithreading wcf windows-services

我们有一个Web服务,它将请求发送到承载WCF服务进行处理的Windows服务。

界面很简单:

namespace MyApp
{
    [ServiceContract]
    public interface IMyApp
    {   
        [OperationContract]
        string DoSomething(string xml);
    }
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    class MyAppWcf : IMyApp
    {
        public string DoSomething(string xml) 
        { 
            Customer customer = GlobalObject.GetCustomer(xml); //millisecs 
            return customer.DoSomething(xml); //Takes 5-10 seconds
        }
    }
}

GlobalObject在WindowsService.OnStart()上实例化,包含客户对象所需的所有静态数据。 界面DoSomething()将被调用到ca. 30个不同的客户。

问题:
1.现在的默认线程行为是什么?每个电话都要等到最后一个电话完成吗? 2.改变InstanceContextMode会有什么影响?

REAL 问题:
最多有1000个客户对象,可以并行调用2个不同的客户对象,但同一个客户对象不能。例如
DoSomething(“客户1”); =>继续前进。 10秒内回答
DoSomething(“客户2”); =>与上述呼叫并行前进 DoSomething(“客户2”); =>将等待DoSomething的最后一次调用(“客户2”)完成

我的服务行为设置应该是什么?我是否必须实现锁定机制以防止同时处理同一个对象多次?

感谢。

编辑2:GlobalObject.GetCustomer()只是从字典中检索XML中提到的客户。

2 个答案:

答案 0 :(得分:2)

行。我不确定在使用ConcurrencyMode实例化时我是否知道PerCall被忽略,但是查看我自己的项目,我使用PerCall实例化并且没有为{{1}指定任何值}}。显然,我确实知道这一点,并且没有在我的代码中记录它。现在已经纠正了。

我的项目很像您描述的项目,我使用ConcurrencyMode正如我已经提到的那样。这就是这意味着什么。

  • Client1 => InstanceContextMode.PerCall
  • Client2 =&gt; MyAppWcfInst.DoSomething( "<customer id=A/>" );
  • Client3 =&gt; MyAppWcfInst.DoSomething( "<customer id=B/>" );

所有三个客户端将同时与您的WCF服务进行交互,但每个客户端都有自己的实例并在单独的线程中运行。因此,虽然每个客户端的每个调用都是单线程的,但它们可以同时处于活动状态。这意味着多个客户端可以同时访问Customer对象列表。

Client1和Client2可以并行运行,因为它们处理不同的Customer对象,但Client3需要等到Client2完成才能与CustomerB“做某事”。所有这些意味着您需要在每个Customer对象中同步访问。换句话说,MyAppWcfInst.DoSomething( "<customer id=B/>" );方法中的逻辑需要具有同步锁定,以防止多个客户端同时在客户上运行。

Customer.DoSomething()

这是我的WCF服务的工作方式。希望这会有所帮助。

答案 1 :(得分:1)

使用PerCall,您将获得并行处理的服务请求,每个请求都在MyAppWcf类的不同实例上。如果没有可用于发送它们的免费.NET线程池线程,则请求只需等待较早的一个完成。 如果您将其更改为Single,则除非您将ConcurrencyMode设置为Multiple,否则将序列化请求。

您真正关心的是GobalObject方法的并发访问安全性如何:如果这不安全,则上述代码也不是。

与Customer.DoSomething方法类似,如果它触及任何共享数据(例如它自己调用GlobalObject)。

我不明白你的意思是“一次只能处理一个客户对象”。如果这确实是真的,那么无论如何你都需要避免并行执行。