WCF InstanceContextMode.Multiple问题

时间:2009-02-26 21:09:48

标签: wcf concurrency

所以我在WinForms应用程序中托管WCF服务。我有以下

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
         InstanceContextMode = InstanceContextMode.PerCall)]
public class Test : ITest
{
    public string TestIt(string input)
    {
        Thread.Sleep(5000);
        return "test";
    }
}

我正在使用命名管道,并且有两个另一个应用程序的实例,它们充当上述WCF服务的客户端(在WinForms应用程序中运行)。我认为基于Multiple的ConcurrencyMode设置,当Client1调用Test Service时,Client2不必等到第一个调用完成。但是,当Client1调用TestIt时,Client2会阻塞,直到来自Client1的调用完成!?!?!根据上述设置,它不应每次都创建一个新实例吗?

此外,保持托管WCF服务响应的WinForms应用程序的最佳方法是在单独的线程上运行WCF服务吗?

注意:在Test类上设置[CallbackBehavior(UseSynchronizationContext = false)]并不能解决问题。该服务一次只响应一个请求。

3 个答案:

答案 0 :(得分:10)

听起来你想设置这个

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.usesynchronizationcontext.aspx

为假。默认情况下,如果在service.Open()发生时存在同步上下文,WCF将对其进行拾取并使用它。但是如果你不想要这个功能,这个标志就是如何关闭它。

答案 1 :(得分:4)

在深入研究之后,我能够使其正常工作的唯一方法是在WinForms应用程序中的单独线程上启动ServiceHost。如果不进行此设置,则ConcurrencyMode和InstanceContextMode属性不执行任何操作。

答案 2 :(得分:1)

我遇到了同样的问题。

我实现Callback的类也包含wcf客户端的方法,所以当我从远程服务调用某个方法并且服务调用Callback方法时,我正在创建一个死锁。

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class AppContext : ICustomerOrderCallback
{
    //WCF Proxy client
    private CustomerOrderClient _client = null;

    public AppContext()
    {
        InstanceContext context = new InstanceContext(this); 
        _client = new CustomerOrderClient(context);
        _client.Subscribe();  //Remote method for subscribing callback
    }

    public void SendMessage(string message)
    {
        //Calling Remote method 
        _client.SendMessage(message);
    }

    //....code

    //callback method
    public void OnMessageReceived(string message)
    {
        //.....code
    }
}

所以我为回调创建了一个单独的类,为它添加了属性CallBehavior,一切正常。

public class AppContext
{
    private CustomerOrderClient _client = null;

    private MyCallbackClass _myCallback = null;
    public AppContext()
    {
        _myCallback = new MyCallbackClass();
        InstanceContext context = new InstanceContext(_myCallback); 
        _client = new CustomerOrderClient(context);
        _client.Subscribe();
    }

    public void SendMessage(string message)
    {
        _client.SendMessage(message);
    }
}

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyCallbackClass : ICustomerOrderCallback
{
    public void OnMessageReceived(string message)
    {
        //.....code
    }
}