关于WCF 自我寄宿(Self-Hosting) 执行长时间任务并发问题

时间:2021-03-07 20:34:01
这几天在研究服务器的并发性能,当服务的方法需要执行长时间的任务时,发现WCF宿主到Console程序,或者宿主到Windows Service的情况下,没有体现很好的并发的性能,但是宿主到IIS的时候,可以体现并发的性能(我的测试环境是:Windows Server 2008 R2,双核,16G内存)。怀疑是最大工作线程的原因,因为我的业务需求不能将WCF宿主到IIS,必须宿主到Windows Service或者WinFrom,并发问题是一个瓶颈,不知道怎么解决???请大神帮帮忙。

这里是源代码下载: http://pan.baidu.com/s/1pKHzizh

1.服务代码,通过Thread.Sleep(millisecondsSleep),模拟服务执行一定长时间的任务,参数millisecondsSleep有客户端传入,我这里设置位8秒,也就是说服务执行需要8秒时间:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
              UseSynchronizationContext = false,
              ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class TestService : ITestService
    {
         static int count = 0;
         public void DoWork(String id, int millisecondsSleep)
        {
            count++;
            Console.WriteLine("DoWork [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "] Start :" + id + "  count:" + count);
            Thread.Sleep(millisecondsSleep);   //模式服务器执行长时间操作,由客户端传入
            Console.WriteLine("DoWork [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "] END :" + id + "  count:" + count);
        }
     }


2. 服务器端app.config配置(宿主到Console、宿主到WindowsServic 配置一样):

<?xml version="1.0"?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="100"/>
    </connectionManagement>
  </system.net>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances="1000"/>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment  multipleSiteBindingsEnabled="true"/>
    <services>
      <service name="WCF.TestService">
        <endpoint address="http://localhost:8009/TestService" binding="basicHttpBinding" name="webwcfService" contract="WCF.ITestService"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8009/TestService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
    </modules>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>


3. 客户端代码:执行100个并发呼叫:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("====客户端准备中:按任意键开始测试...");
            Console.ReadLine();

            ThreadPool.SetMinThreads(100, 100);
            for (int i = 0; i < 100; i++)
            {
                System.Threading.ThreadPool.QueueUserWorkItem(DoWork, Convert.ToString(i));
            }
            Console.ReadLine();
        }

        static void DoWork(Object key)
        {
            try
            {
                Console.WriteLine("DoWork [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "] Start :" + key);
                TestServiceClient client = new TestServiceClient();
                client.DoWork(Convert.ToString(key), 8 * 1000);
                //client.DoWork(Convert.ToString(valuei), 10);
                client.Close();
                Console.WriteLine("DoWork [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "] END:" + key);
            }
            catch (Exception ex)
            {
                Console.WriteLine("=============================DoWork [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "] ERROR:" + key + "," + ex.Message);
            }
        }
    }



4. 客户端配置app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*"   maxconnection="100"   />
    </connectionManagement>
  </system.net>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="webwcfService"  />
      </basicHttpBinding>
    </bindings>
        <client>
              <endpoint address="http://localhost:8009/TestService" binding="basicHttpBinding"
                    bindingConfiguration="webwcfService" contract="TestServiceReference.ITestService"
                    name="webwcfService" />
        </client>
    </system.serviceModel>
</configuration>


以下是执行的结果:客户端是同一秒执行呼叫WCF服务,但是服务器端显示有出现并发的情况,但是创建服务对象很慢,1秒才创建2个工作任务,达不到我想要的并发效果。
关于WCF 自我寄宿(Self-Hosting) 执行长时间任务并发问题

5.但是,我将WCF 宿主到IIS上后,再进行测试,就可以出现我想要的并发效果:
关于WCF 自我寄宿(Self-Hosting) 执行长时间任务并发问题

以下是执行结果:服务器端没有输出,所以根据客户执行结果判断是同一秒返回的,所以是并发执行的。
关于WCF 自我寄宿(Self-Hosting) 执行长时间任务并发问题
通过性能监视器查看WCF情况如下:可以看到是100个任务并发执行的。
关于WCF 自我寄宿(Self-Hosting) 执行长时间任务并发问题


通过以上测试,WCF宿主到IIS的情况下,可以很好的并发执行100个任务,但是宿主到其他(Console、WindowsService)的情况,并发性能很差,但是我的需求并不能将WCF宿主到IIS,需要宿主到Windows Service,研究了几天,一直解决不了并发的问题,请各位大神帮忙解决以下。



3 个解决方案

#1


”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread:

static void Main()
{
    ThreadPool.SetMinThreads(100, 100);
    ...
}

#2


引用 1 楼 Forty2 的回复:
”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread:

static void Main()
{
    ThreadPool.SetMinThreads(100, 100);
    ...
}


安装你的建议,问题解决了,确实是ThreadPool的原因,太感谢你了。谢谢。

#3


这里是源码下载地址:http://download.csdn.net/detail/lucas365/9735594 

#1


”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread:

static void Main()
{
    ThreadPool.SetMinThreads(100, 100);
    ...
}

#2


引用 1 楼 Forty2 的回复:
”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread:

static void Main()
{
    ThreadPool.SetMinThreads(100, 100);
    ...
}


安装你的建议,问题解决了,确实是ThreadPool的原因,太感谢你了。谢谢。

#3


这里是源码下载地址:http://download.csdn.net/detail/lucas365/9735594