C# Windows服务/WCF和线程,初学者问题

C# Windows服务/WCF和线程,初学者问题,c#,multithreading,wcf,windows-services,C#,Multithreading,Wcf,Windows Services,我们有一个web服务,它将请求发送到承载WCF服务进行处理的windows服务 界面很简单: namespace MyApp { [ServiceContract] public interface IMyApp { [OperationContract] string DoSomething(string xml); } [ServiceBehavior(InstanceContextMode = InstanceC

我们有一个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()最多可调用30个不同的客户端

问题:
1.现在默认的线程行为是什么?每次通话都要等到最后一次通话结束吗?
2.更改InstanceContextMode将产生什么影响?

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

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

谢谢


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

使用PerCall,您将并行处理对服务的请求,每个请求都在MyAppWcf类的不同实例上。如果没有可用的.NET线程池线程来分派请求,则请求只需等待较早的线程完成。 如果将其更改为Single,则请求将被序列化,除非将ConcurrencyMode设置为Multiple

您真正关心的应该是并发访问GobalObject方法的安全性:如果这不是ADSafe,那么上面的代码也不是

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


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

好的。我不知道在使用
PerCall
实例化时是否忽略了
ConcurrencyMode
,但看看我自己的项目,我使用了
PerCall
实例化,并且没有为
ConcurrencyMode
指定任何值。所以很明显,我确实知道这一点,只是没有在我的代码中记录它。这一点现在得到纠正

我的项目与您描述的项目非常相似,我使用了
InstanceContextMode.PerCall
,正如我前面提到的。这就是它的意思

  • Client1=>
    MyAppWcfInst.DoSomething(“”)
  • Client2=>
    MyAppWcfInst.DoSomething(“”)
  • Client3=>
    MyAppWcfInst.DoSomething(“”)
这三个客户端将同时与您的WCF服务交互,但每个客户端都有自己的实例并在单独的线程中运行。因此,虽然每个客户端的每个调用都是单线程的,但它们可以同时处于活动状态。这意味着多个客户端可以同时访问客户对象列表

class Customer
{
    private object _sync = new object();

    public string DoSomething( string xml )
    {
        lock (_sync)
        {
            // put your logic here...
        }
    }
}
Client1和Client2可以并行运行,因为它们处理不同的客户对象,但Client3需要等到Client2完成后才能与CustomerB“做点什么”。这意味着您需要在每个客户对象内同步访问。换句话说,
Customer.DoSomething()
方法中的逻辑需要有一个同步锁,以防止多个客户端同时对客户进行操作

class Customer
{
    private object _sync = new object();

    public string DoSomething( string xml )
    {
        lock (_sync)
        {
            // put your logic here...
        }
    }
}

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

可能有1000个客户对象。每个客户对象本身都是线程安全的,但同一个对象不能同时运行。e、 g.客户1和客户2可以并行处理。GlobalObject.GetCustomer是安全的(只读)。请重新阅读Matt Davis的答案。。。我一直明白InstanceContextMode为PerCall时会忽略ConcurrencyMode,MSDN文档就是这么说的。所以我认为你已经有了并行执行。。。不过,我要检查一下,以防文档出错。+1@Chris Dickson。我已经根据这些信息更新了我的回复,这些信息显然是我在途中忘记的。谢谢,谢谢,马特,这正是我需要的。