この問題は元々、大量のデータが返されるWCFデータサービス(OData)(〜3MB)で発生し、データを消費するアプリケーション(MVC Webサイト)が散発的に一部のリクエストでハングし、最終的にタイムアウトしました。 。
この問題は、より小さなデータペイロードで再現される可能性がありますが、発生するまでに長い時間がかかります。この問題は、CassiniとIIS 7の両方で再現されています。IISを実行すると、ハングしたW3ワーカープロセスがタイムアウトするまで「SendResponse」状態のままであることがわかりました。
問題の原因を絞り込むために、ASP.NETサイトからコンテンツを順番にダウンロードするコンソールアプリを作成しました。この問題は、WCFデータサービス(OData)、標準のWCFサービス、および同様のデータをHttpResponseオブジェクトに直接出力するWebフォームページで再現されました。使用されているサンプルコードは、標準のWCFサービスを例として使用しています(複製しようとしているユーザーのセットアップを容易にするため)。
コンソールアプリクライアント:
static void Main(string[] args)
{
Console.ReadKey(); // press any key to start test
do
{
var req = WebRequest.Create(new Uri("http://localhost:26332/WCFTest.svc/GetData"));
var response = req.GetResponse();
using (var stream = response.GetResponseStream())
{
var content = new StreamReader(stream).ReadToEnd();
}
} while (true);
}
WCFサービス:
public class Service1 : IService1
{
public TestClass[] GetData()
{
return Enumerable
.Range(0, 15000)
.Select(i => new TestClass{ ID = "1" })
.ToArray();
}
}
[DataContract]
public class TestClass
{
[DataMember]
public string ID { get; set; }
}
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "GetData")]
TestClass[] GetData();
}
Webサービスを何度も呼び出した後(これは実行ごとに異なりますが、通常は30未満です)、GetResponseStream呼び出しはハングします。
何がうまくいかないのか、問題の原因を絞り込む方法についてのアイデアをいただければ幸いです。
サービスweb.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService2.Service1" >
<endpoint
address=""
binding="webHttpBinding"
contract="WcfService2.IService1"
behaviorConfiguration="webHttp"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
WCFデータサービスコード:
public class Service1 : DataService<ODataContext>
{
public static void InitializeService(DataServiceConfiguration configuration)
{
configuration.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
}
}
public class ODataContext
{
public IQueryable<TestClass> Test
{
get
{
return Enumerable
.Range(0, 15000)
.Select(i => new TestClass {ID = "1"})
.AsQueryable();
}
}
}
public class TestClass
{
public string ID { get; set; }
}