gpt4 book ai didi

从 Entity Framework 返回结果时 WCF 调用失败

转载 作者:行者123 更新时间:2023-12-04 15:57:56 25 4
gpt4 key购买 nike

我使用 Entity Framework 和 WCF 创建了一个简单的测试解决方案。我在服务契约(Contract)中只有一个函数,称为 GetAllCustomers(),它从数据库中检索客户并将其返回给客户端。客户端应用程序调用该函数并将客户姓名写入控制台。

当我通过代理从客户端调用 GetAllCustomers() 时,我收到一个带有消息的 CommunicationException

An error occurred while receiving the HTTP response to http://localhost:8000/Service1. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

内部异常是System.Net.WebException:

The underlying connection was closed: An unexpected error occurred on a receive.

下一级内部异常是System.IO.IOException:

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

最后的内部异常是System.Net.Sockets.SocketException:

An existing connection was forcibly closed by the remote host

这是客户端代码:

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 block 来绕过数据库,效果很好!

我一开始以为可能是数据库查询时间过长的超时问题。但是,我的测试代码在那里有 45 秒的休眠,它仍然可以将数据返回给客户端。原始代码仅在大约 3 秒后给出了异常。

此外,如果我通过直接实例化 WCF 服务而不是通过端点/代理来调用原始函数(使用 foreach block ),它也可以正常运行并返回数据库中的所有客户。

最后我觉得可能是返回的数据集太大的问题,所以我修改了foreach block ,在结果中添加了前5个客户后插入了一个break语句,还是报错了。

那么,还有什么可能导致这种情况?

最佳答案

很难判断可能是什么问题。您可以打开 WCF 跟踪和诊断,这可以为您提供更多详细信息。

让您快速前进 - 在您的网络(或应用程序)配置中:

1) 在配置元素下的任意位置添加 System.Diagnostics 部分。您可以将路径替换为您希望文件存储在的任何路径。

<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelMessageLoggingListener">
<filter type="" />
</add>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Warning, ActivityTracing" propagateActivity="true">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelTraceListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\temp\services_messages.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelMessageLoggingListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
<filter type="" />
</add>
<add initializeData="C:\temp\services_tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
<filter type="" />
</add>
</sharedListeners>
</system.diagnostics>

2) 在 system.ServiceModel 下添加以下内容:

<diagnostics wmiProviderEnabled="false">
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>

3) 在 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\下启动 SvcTraceViewer.exe。加载消息跟踪 (services_messages.svclog) 和服务跟踪日志 (services_tracelog.svclog)。您可以在工具中拖放文件或打开一个文件然后添加另一个

4) 寻找红色粗体字母表示问题。

如果您想让编辑 WCF 配置的体验更愉快,您可以使用 SvcConfigEditor.exe,它位于与 SvcTraceViewer.exe (#3) 相同的文件夹下。只需打开配置文件,您应该会看到 Diagnostics 文件夹,您可以在其中启动/停止和配置诊断。

关于从 Entity Framework 返回结果时 WCF 调用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14089390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com