首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows服务/ WCF和线程,初学者提问

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

Stack Overflow用户
提问于 2010-11-18 15:20:06
回答 2查看 1.9K关注 0票数 3

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

接口很简单:

代码语言:javascript
复制
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. 现在默认的线程行为是什么?每一次调用都要等到最后一次调用结束吗? InstanceContextMode?

  • 会有什么影响?

问题:

有多达1000个客户对象,两个不同的客户对象可以并行调用,但同一个客户对象不能。例如:

DoSomething("Customer 1");=>继续前进。10秒后回答

DoSomething("Customer 2");=>与上述调用并行进行。

DoSomething("Customer 2");=>将等待DoSomething("Customer 2")的最后调用完成

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

谢谢。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-18 16:51:33

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

我的项目非常像您描述的那样工作,正如我已经提到的那样,我使用了InstanceContextMode.PerCall。这是什么意思。

MyAppWcfInst.DoSomething( "<customer id=A/>" );

  • Client2 MyAppWcfInst.DoSomething( "<customer id=B/>" );

  • Client3 MyAppWcfInst.DoSomething( "<customer id=B/>" );

  • Client1 =>

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

Client1和Client2可以并行操作,因为它们处理不同的客户对象,但是Client3需要等到Client2完成后才能使用CustomerB“做一些事情”。这意味着您需要同步每个Customer对象内的访问。换句话说,Customer.DoSomething()方法中的逻辑需要有一个同步锁,以防止多个客户机同时对客户进行操作。

代码语言:javascript
复制
class Customer
{
    private object _sync = new object();

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

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

票数 2
EN

Stack Overflow用户

发布于 2010-11-18 16:30:38

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

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

同样,对于Customer.DoSomething方法,如果它触及任何共享数据(例如调用GlobalObject本身)。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4216379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档