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

洛客 2017-01-11 02:47:34
这几天在研究服务器的并发性能,当服务的方法需要执行长时间的任务时,发现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个工作任务,达不到我想要的并发效果。


5.但是,我将WCF 宿主到IIS上后,再进行测试,就可以出现我想要的并发效果:


以下是执行结果:服务器端没有输出,所以根据客户执行结果判断是同一秒返回的,所以是并发执行的。

通过性能监视器查看WCF情况如下:可以看到是100个任务并发执行的。



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



...全文
368 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
洛客 2017-01-12
  • 打赏
  • 举报
回复
这里是源码下载地址:http://download.csdn.net/detail/lucas365/9735594
洛客 2017-01-11
  • 打赏
  • 举报
回复
引用 1 楼 Forty2 的回复:
”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread: static void Main() { ThreadPool.SetMinThreads(100, 100); ... }
安装你的建议,问题解决了,确实是ThreadPool的原因,太感谢你了。谢谢。
Forty2 2017-01-11
  • 打赏
  • 举报
回复
”一秒新开两个线程“看起来象是ThreadPool在限速。你试试在服务端,也设置MinThread: static void Main() { ThreadPool.SetMinThreads(100, 100); ... }

110,500

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧