WCF REST服务:InstanceContextMode.PerCall不起作用

5

我为WCF实现了一个REST服务。该服务提供一个函数,可以被许多客户端调用,这个函数需要超过1分钟的时间才能完成。因此,我希望为每个客户端使用一个新的对象,以便可以同时处理多个客户端。

我的接口如下所示:

[ServiceContract]
public interface ISimulatorControlServices
{
    [WebGet]
    [OperationContract]
    string DoSomething(string xml);
}

并且它的(测试)实现:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall]
public class SimulatorControlService : SimulatorServiceInterfaces.ISimulatorControlServices
{
    public SimulatorControlService()
    {
        Console.WriteLine("SimulatorControlService started.");
    }

    public string DoSomething(string xml)
    {
        System.Threading.Thread.Sleep(2000);
        return "blub";
    }
}

现在的问题是:如果我使用一个创建10(或任意数量)线程的客户端,每个线程都调用服务,它们并不并发运行。这意味着,这些调用是一个接一个地处理的。有人知道为什么会出现这种情况吗?
补充说明:客户端代码如下:
线程的生成:
        for (int i = 0; i < 5; i++)
        {
            Thread thread = new Thread(new ThreadStart(DoSomethingTest));
            thread.Start();
        }

方法:

  private static void DoSomethingTest()
    {
        try
        {
            using (ChannelFactory<ISimulatorControlServices> cf = new ChannelFactory<ISimulatorControlServices>(new WebHttpBinding(), "http://localhost:9002/bla/SimulatorControlService"))
            {
                cf.Endpoint.Behaviors.Add(new WebHttpBehavior());

                ISimulatorControlServices channel = cf.CreateChannel();

                string s;

                int threadID = Thread.CurrentThread.ManagedThreadId;

                Console.WriteLine("Thread {0} calling DoSomething()...", threadID);

                string testXml = "test";

                s = channel.StartPressureMapping(testXml);

                Console.WriteLine("Thread {0} finished with reponse: {1}", threadID, s);
            }

        }
        catch (CommunicationException cex)
        {
            Console.WriteLine("A communication exception occurred: {0}", cex.Message);
        }
    }

提前感谢您!


你是如何生成客户端请求的?能展示一些相关代码吗?请注意,你可以编辑你的问题以添加细节。 - Jeroen
如果您的服务不使用共享资源,您可以将ServiceBehavior更改为Single,并使用Concurrency Multiple。这将为您提供一个服务实例,该实例是多线程的(每个调用一个线程)。 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Multiple)] - JanW
这让我感到惊讶,本以为你的代码会按照你的预期工作。但也许这个 MSDN 线程可以帮助你?(http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/593df2bb-9505-49f2-92e9-e6e925d95830) - Jeroen
找到解决方案了,感谢 @Jeroen![ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext=false)] - Cleo
太好了!不要忘记在24小时后回答并接受自己的问题,这样其他人就可以直接找到解决方案了! - Jeroen
1个回答

2
由于该服务由GUI控制,因此需要使用"UseSynchronizationContext"属性来解决问题:
  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext=false)] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接