EntityFrameworkとWCFを使用して簡単なテストソリューションを作成しました。サービスコントラクトにはGetAllCustomers()
、データベースから顧客を取得してクライアントに返すという関数が1つだけあります。クライアントアプリは関数を呼び出し、顧客名をコンソールに書き込みます。
GetAllCustomers()
クライアントからプロキシ経由で電話をかけるCommunicationException
と、次のメッセージが表示されます。
へのHTTP応答の受信中にエラーが発生しました
http://localhost:8000/Service1
。これは、HTTPプロトコルを使用していないサービスエンドポイントバインディングが原因である可能性があります。これは、サーバーによってHTTP要求コンテキストが中止されたことが原因である可能性もあります(おそらくサービスのシャットダウンが原因です)。詳細については、サーバーログを参照してください。
内部の例外はSystem.Net.WebException
次のとおりです。
基になる接続が閉じられました:受信時に予期しないエラーが発生しました。
次のレベルの内部例外は次のSystem.IO.IOException
とおりです。
トランスポート接続からデータを読み取れません:既存の接続がリモートホストによって強制的に閉じられました。
そして最後の内部例外はSystem.Net.Sockets.SocketException
:
既存の接続がリモートホストによって強制的に閉じられました
クライアントコードは次のとおりです。
static void Main(string[] args)
{
Console.WriteLine("Press Enter to begin.");
Console.ReadLine();
ServiceReference1.Service1Client MyService = new ServiceReference1.Service1Client();
CUSTOMER[] cl = MyService.GetAllCustomers();
foreach (CUSTOMER c in cl)
{
Console.WriteLine(c.CUSTFNAME + " " + c.CUSTLNAME);
}
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
ホストアプリケーションのコードは次のとおりです。
static void Main(string[] args)
{
ServiceHost hostA = null;
try
{
hostA = new ServiceHost(typeof(Service1), new Uri("http://localhost:8000") );
hostA.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "Service1");
hostA.Open();
Console.WriteLine();
Console.WriteLine("Host started. Press Enter to terminate host.");
Console.ReadLine();
}
finally
{
if (hostA.State == CommunicationState.Faulted)
hostA.Abort();
else
hostA.Close();
}
}
関数のサービスライブラリコードは次のとおりです。
public HashSet<CUSTOMER> GetAllCustomers()
{
var db = new TRS11Entities();
HashSet<CUSTOMER> TheCusts = new HashSet<CUSTOMER>();
foreach (CUSTOMER c in db.CUSTOMERs)
{
TheCusts.Add(c);
}
//CUSTOMER TestCust1 = new CUSTOMER();
//TestCust1.CUSTFNAME = "Joe";
//TestCust1.CUSTLNAME = "Schmoe";
//CUSTOMER TestCust2 = new CUSTOMER();
//TestCust2.CUSTFNAME = "Peter";
//TestCust2.CUSTLNAME = "Pumpkineater";
//TheCusts.Add(TestCust1);
//System.Threading.Thread.Sleep(45000);
//TheCusts.Add(TestCust2);
return TheCusts;
}
不思議なことに、foreachブロックをその下のコメントアウトされたコードに置き換えてデータベースをバイパスすると、うまく機能します。
私は最初、データベースクエリに時間がかかりすぎるというタイムアウトの問題である可能性があると考えました。ただし、私のテストコードには45秒間のスリープがあり、それでもデータはクライアントに正常に返されます。元のコードでは、わずか約3秒後に例外が発生します。
また、エンドポイント/プロキシ経由ではなく、WCFサービスを直接インスタンス化して元の関数(foreachブロックを使用)を呼び出すと、正常に実行され、データベース内のすべての顧客が返されます。
最後に、返されたデータセットが大きすぎることが問題である可能性があると考えたため、foreachブロックを変更し、最初の5人の顧客を結果に追加した後にbreakステートメントを挿入しましたが、それでも例外が発生しました。
それで、他に何がこれを引き起こしている可能性がありますか?