托管在Windows服务C#WCF 5分钟后进入闲置状态 [英] c# wcf hosted in windows service goes idle after 5 minutes

查看:178
本文介绍了托管在Windows服务C#WCF 5分钟后进入闲置状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我里面有一个Windows服务托管的WCF服务。 (所以它不是托管在IIS中,它是selfhosted)

中的应用使得有可能通过HTTP接收的测量。这些都是当前正在写入到一个txt文件。

我也有一个任务配置,在特定时间运行的每一天。

我的问题是,当我不通过HTTP接收测量ATLEAST 5分钟服务似乎进入空闲状态。

我注意到,5分钟后需要30秒的服务响应。如果我发送测量通过http 30秒后​​,我得到一个快速的反应。

这可能是什么问题?

的app.config

 < XML版本=1.0&GT?;
<结构>
  < configSections>
    <! - 有关实​​体框架配置的详细信息,请访问http://go.microsoft.com/fwlink/?LinkID=237468  - >
    <节名称=的EntityFrameworkTYPE =System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,的EntityFramework,版本= 6.0.0.0,文化=中性公钥= b77a5c561934e089requirePermission =FALSE/>
    < sectionGroup名=的applicationSettingsTYPE =System.Configuration.ApplicationSettingsGroup,系统,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089>
      <节名称=Applicatie.Properties.SettingsTYPE =System.Configuration.ClientSettingsSection,系统,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089requirePermission =FALSE/>
    < / sectionGroup>
  < / configSections>
  <的ConnectionStrings>

  < /的ConnectionStrings>
  < system.serviceModel>

    <绑定>

      <的WebHttpBinding>
        <绑定名称=LargeWebmaxBufferSize =1500000maxBufferPoolSize =1500000
          maxReceivedMessageSize =20亿transferMode =流媒体>
          < readerQuotas MAXDEPTH =32maxStringContentLength =656000maxArrayLength =656000
            maxBytesPerRead =656000maxNameTableCharCount =656000/>
        < /装订>
      < /的WebHttpBinding>
    < /绑定>
    <服务>
      <服务名称=Applicatie.ApplicatiebehaviorConfiguration =代理>
        <主机>
          < baseAddresses>
            <新增baseAddress =HTTP://本地主机:5001 / Applicatie/>
          < / baseAddresses>
        < /主机>
        <端点地址=绑定=的WebHttpBindingbindingConfiguration =LargeWebbehaviorConfiguration =webBehavior合同=Applicatie.IApplicatie/>
      < /服务>
    < /服务>
    <行为>
      < endpointBehaviors>
        <行为NAME =webBehavior>
          < webHttp />
          < CorsSupport />
        < /行为>
      < / endpointBehaviors>
      < serviceBehaviors>
        <行为NAME =代理>
          < serviceMetadata httpGetEnabled =真httpsGetEnabled =真/>
          < serviceDebug httpHelpPageEnabled =真includeExceptionDetailInFaults =真/>
        < /行为>
      < / serviceBehaviors>
    < /行为>
    <扩展>
      < behaviorExtensions>
        <添加名称=CorsSupportTYPE =WebHttpCors.CorsSupportBehaviorElement,WebHttpCors,版本= 2.0.0.0,文化=中性公钥=空/>
      < / behaviorExtensions>
    < /扩展>
  < /system.serviceModel>
  <启动>
    < supportedRuntime版本=4.0版的SKU =NETFramework,版本= V4.5/>
  < /启动>


  <运行>
    < assemblyBinding的xmlns =瓮:架构 - 微软COM:asm.v1>
      < dependentAssembly>
        < assemblyIdentity名=的EntityFramework公钥=b77a5c561934e089文化=中性/>
        < bindingRedirect oldVersion =0.0.0.0-5.0.0.0NEWVERSION =5.0.0.0/>
      < / dependentAssembly>
    < / assemblyBinding>
  < /运行>
  <的EntityFramework>
    < defaultConnectionFactory TYPE =System.Data.Entity.Infrastructure.SqlConnectionFactory,的EntityFramework/>
    <! - <供应商>
      <供应商invariantName =System.Data.SqlClient的TYPE =System.Data.Entity.SqlServer.SqlProviderServices,EntityFramework.SqlServer/>
    &所述; /提供商&GT  - →;
  < /的EntityFramework>
< /结构>
 

解决方案

这似乎是这个问题,我们也有。我们有很多的自我托管服务。如果一段时间(约1分钟)服务没有收到请求时,它变得空闲,而下一个电话实在是太慢了。

所以,原因和解决办法<一href="https://social.msdn.microsoft.com/Forums/vstudio/en-US/2dc57a71-6708-4a38-b7a9-8230fdd5675f/why-is-a-wcf-services-responce-slow-after-being-idle-for-more-than-15-seconds?forum=wcf"相对=nofollow>这里描述

我也印证了这一办法修补的情况下帮助。

从那里引用:

  

我已经证实了我们的开发者,这是一个已知的问题。原因确实与线程池和线程超时。   一个可能的解决方法是调用ThreadPool.UnsafeQueueNativeOverlapped方法在很短的时间间隔,以保持线程可用。

 类节目
{
    静态无效的主要(字串[] args)
    {
        使用(VAR主机=新的ServiceHost(typeof运算(服务1)))
        {
            ThreadPool.QueueUserWorkItem(
                新WaitCallback(委托
            {
                而(真)
                {
                    Thread.sleep代码(TimeSpan.FromSeconds(100));
                    QueueDummyIOCPWork();
                }
            }));

            host.Open();
            Console.WriteLine(服务运行...);
            Console.ReadKey(假);
        }
    }

    私有静态不安全无效QueueDummyIOCPWork()
    {
        重叠OVL =新的重叠();
        NativeOverlapped * pOvl = NULL;
        pOvl = ovl.Pack((A,B,C)=&GT; {Overlapped.Unpack(pOvl); Overlapped.Free(pOvl);},NULL);
        ThreadPool.UnsafeQueueNativeOverlapped(pOvl);
    }
}
 

I have a WCF service hosted inside a Windows Service. (SO its not hosted in IIS, it is selfhosted)

The application makes it possible to receive measurements through HTTP. These are currently being written to a txt file.

I also have a Task configured that runs everyday at a specific time.

The problem i have is that when i dont receive a measurement through HTTP for atleast 5 minutes the service seems to go idle.

I noticed that after 5 minutes it takes 30 seconds for the service to respond. After 30 seconds if i send measurements through http i get a fast response.

What could be the problem?

app.config

<?xml version="1.0"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="Applicatie.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <connectionStrings>

  </connectionStrings>
  <system.serviceModel>

    <bindings>

      <webHttpBinding>
        <binding name="LargeWeb" maxBufferSize="1500000" maxBufferPoolSize="1500000"
          maxReceivedMessageSize="2000000000" transferMode="Streamed">
          <readerQuotas maxDepth="32" maxStringContentLength="656000" maxArrayLength="656000"
            maxBytesPerRead="656000" maxNameTableCharCount="656000" />
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="Applicatie.Applicatie" behaviorConfiguration="Proxy">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:5001/Applicatie"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="LargeWeb" behaviorConfiguration="webBehavior" contract="Applicatie.IApplicatie"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp/>
          <CorsSupport />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Proxy">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="CorsSupport" type="WebHttpCors.CorsSupportBehaviorElement, WebHttpCors, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>


  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
    <!--<providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>-->
  </entityFramework>
</configuration>

解决方案

It seems like the issue we also had. we have many self hosted services. If for some time (~1 min) service receives no requests it becomes idle, and next call is really slow.

So the reasons and solution described here

I also confirm this fix helped in our case.

Quote from there:

I have confirmed with our developers that this is a known issue. The cause is indeed related to ThreadPool and thread timeout. One possible workaround is call ThreadPool.UnsafeQueueNativeOverlapped method in short time interval to keep thread available.

 class Program
{
    static void Main(string[] args)
    {
        using (var host = new ServiceHost(typeof(Service1)))
        {
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(delegate
            {
                while (true)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(100));
                    QueueDummyIOCPWork();
                }
            }));

            host.Open();
            Console.WriteLine("Service running...");
            Console.ReadKey(false);
        }
    }

    private static unsafe void QueueDummyIOCPWork()
    {
        Overlapped ovl = new Overlapped();
        NativeOverlapped* pOvl = null;
        pOvl = ovl.Pack((a, b, c) => { Overlapped.Unpack(pOvl); Overlapped.Free(pOvl); }, null);
        ThreadPool.UnsafeQueueNativeOverlapped(pOvl);
    }
}

这篇关于托管在Windows服务C#WCF 5分钟后进入闲置状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆