我使用Entity Framework和WCF创建了一个简单的测试解决方案。我在服务合同中只有一个函数,称为GetAllCustomers()
,它从数据库中检索客户并将它们返回给客户端。客户端应用程序调用该函数并将客户名称写入控制台。
当我通过代理从客户端拨打GetAllCustomers()
时,我会收到CommunicationException
的消息,
收到
http://localhost:8000/Service1
的HTTP响应时发生错误。这可能是由于服务端点绑定不使用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语句,我仍然得到了异常。 / p>
那么,还有什么可能导致这个?
答案 0 :(得分:2)
很难说出问题所在。您可以启用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 \ start SvcTraceViewer.exe下。加载消息跟踪(services_messages.svclog)和服务跟踪日志(services_tracelog.svclog)。您可以在工具中拖放文件或打开文件,然后添加另一个
4)找出问题的红色粗体字母。
如果您想让编辑WCF配置的体验更加可口,可以使用SvcConfigEditor.exe,它位于与SvcTraceViewer.exe(#3)相同的文件夹下。只需打开配置文件,您就会看到Diagnostics文件夹,它允许您启动/停止和配置诊断。
答案 1 :(得分:1)
我认为问题是来自实体框架的CUSTOMER类型包含详细记录(销售等)的集合(容器类型),这使得数据太大。我最终创建了一个没有那些的新类型,之后它运行良好。
答案 2 :(得分:0)
如果DataContext.ContextOptions.ProxyCreationEnabled = true更改为false
DataContext.ContextOptions.ProxyCreationEnabled = true
OR
返回克隆客户
公共类客户:ICloneable { Public int Id { 得到; 组; }
public object Clone()
{
var cloneObject = new Customer();
cloneObject.Id=this.Id;
return cloneObject;
}
}
public HashSet GetAllCustomers() { var db = new TRS11Entities(); HashSet TheCusts = new HashSet(); foreach(db.CUSTOMER中的CUSTOMER c) { TheCusts.Add(c.Clone()); }
//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;
}