【问题标题】:WCF InstanceContextMode.Multiple issuesWCF InstanceContextMode.Multiple 问题
【发布时间】:2009-02-26 21:09:48
【问题描述】:

所以我在 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 调用测试服务时,Client2 不必等到第一次调用完成。但是,当 Client1 调用 TestIt 时,Client2 会阻塞,直到来自 Client1 的调用完成!?!?!不应该每次都根据上面的设置新建一个实例吗?

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

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

【问题讨论】:

    标签: wcf concurrency


    【解决方案1】:

    听起来你想设置这个

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

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

    【讨论】:

    • 在 Test 类上设置 [CallbackBehavior(UseSynchronizationContext = false)] 并不能缓解问题。服务仍然一次只响应一个请求。
    • 我也有同样的问题。如果这不是您问题的解决方案,为什么会接受这个答案?你用别的方法解决了吗?
    • 在下面查看他对自己答案的评论 - 这实际上是解决方案。
    【解决方案2】:

    在深入研究后,我能够使其正常工作的唯一方法是在 WinForms 应用程序的单独线程上启动 ServiceHost。如果您不这样做,则设置 ConcurrencyMode 和 InstanceContextMode 属性将无济于事。

    【讨论】:

    • Brian 的回答在这里 AKoran 是正确的。为了防止您遇到线程同步问题,默认情况下,如果您在 winform 中使用 WCF,它将在 winform 上同步。设置 UseSynchronizationContext=false,你会得到 WCF 为你创建一个线程。
    • 我想我一定是做错了,因为设置这些属性仍然会阻止整个 WinForm 应用程序:[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] [CallbackBehavior(UseSynchronizationContext =假)]
    • 啊,有时当您凝视某些东西时,您会失去它……我使用的是 CallBackBehavior 而不是 ServiceBehavior。你是对的。再次感谢大家!
    • 请随意给我一个复选标记,然后将我的答案标记为正确:)
    • 我已经试过了!显然我没有足够的“声誉”来检查或取消选中标记。当/如果我到达那里,我一定会回来给你打分!
    【解决方案3】:

    我遇到了同样的问题。

    我的实现 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 2012-07-19
      相关资源
      最近更新 更多