托管在 Windows 服务中的 c# wcf 在 5 分钟后空闲

标签 c# .net wcf

我在 Windows 服务中托管了一个 WCF 服务。 (所以它没有托管在 IIS 中,它是自托管的)

该应用程序可以通过 HTTP 接收测量值。这些当前正在写入一个 txt 文件。

我还配置了一个每天在特定时间运行的任务。

我遇到的问题是,当我至少 5 分钟没有通过 HTTP 接收到测量值时,服务似乎处于空闲状态。

我注意到 5 分钟后服务需要 30 秒才能响应。 30 秒后,如果我通过 http 发送测量值,我会得到快速响应。

可能是什么问题?

应用程序配置

<?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>

最佳答案

我们似乎也遇到了这个问题。我们有许多自托管服务。如果一段时间(~1 分钟)服务没有收到任何请求,它就会变得空闲,并且下一次调用真的很慢。

所以原因及解决方法described here

我也确认此修复对我们的案例有所帮助。

引自那里:

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 分钟后空闲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33389896/

相关文章:

c# - 如何修改列表属性而不影响同类型的其他列表属性?

.net - 不需要取消的异步方法

WCF 超时 - 线程是否被终止或允许完成

c# - 确定一个点是否位于有界区域内的算法

c# - 将 ADO.NET Entity Framework 与 Advantage 数据库服务器一起使用

c# - 重构 PropertyChangedEventHandler

.net - 您应该在 FormClosing 事件中处理项目吗?

c# - 显示纯文本/代码背后的通信基础

wcf - 简单 WCF SSL Web 服务

c# - 根据 DateTimePicker 值从 MySQL 数据库表中选择所有数据