【发布时间】:2014-01-08 19:54:52
【问题描述】:
我有一个服务器/客户端关系,客户端从服务器中提取一个 ArrayList。如果我将服务器设置为始终发送一个空的 ArrayList,那么我不会收到此错误。很明显,问题是我的数据对于连接来说太大了,而且在所有数据都可以通过之前它就关闭了。
我已经研究了这个问题,并添加了这个问题/答案所建议的功能: https://stackoverflow.com/a/285542/3036134许多解决方案都提出了相同的建议。
我相信我实现了一些错误(我认为这很可能是服务行为 MaxItemsInObjectGraph,因为我仍然遇到同样的错误。不幸的是,我无法弄清楚它有什么问题。这是我的代码:
我收到的错误:
CommunicationException was unhandled. The underlying connection was closed: The connection was closed unexpectedly.
我的 WCF 服务代码:
[ServiceContract]
public interface IModelData
{
[OperationContract]
ArrayList GetData();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, MaxItemsInObjectGraph = 2147483647)]
public class ModelDataClient
{
ChannelFactory<IModelData> HttpFactory;
IModelData HttpProxy;
public ModelDataClient()
{
HttpFactory = new ChannelFactory<IModelData>(
new BasicHttpBinding(),
new EndpointAddress("http://localhost:8000/ModelData"));
HttpProxy = HttpFactory.CreateChannel();
}
public ArrayList GetData()
{
return HttpProxy.GetData();
}
}
[ServiceBehavior(UseSynchronizationContext = false, InstanceContextMode = InstanceContextMode.Single, MaxItemsInObjectGraph = 2147483647)]
public class ModelDataServer : IModelData
{
public delegate ArrayList GetData();
public GetData _GetData { get; set; }
public ModelDataServer()
{
}
public ArrayList GetData()
{
return _GetData();
}
}
我的客户端代码:
public partial class MainForm : Form
{
private ModelDataClient Client;
public MainForm()
{
InitializeComponent();
Client = new ModelDataClient();
}
private void Refresh()
{
ArrayList dataList = Client.GetData();
// ********** ERROR POINTS TO LINE ABOVE!!!!!!!!!!!!!!!!!!!!
// do something with datalist
}
}
我的服务器端代码:
public partial class ScraperForm : Form
{
ServiceHost Host;
ModelDataServer DataServer;
ArrayList Data;
public ScraperForm()
{
InitializeComponent();
#region Start Data Server
DataServer = new ModelDataServer();
DataServer._GetData = new ModelDataServer.GetData(this.GetData);
BasicHttpBinding bhttpb = new BasicHttpBinding();
bhttpb.MaxBufferSize = 2147483647;
bhttpb.MaxReceivedMessageSize = 2147483647;
bhttpb.ReaderQuotas.MaxDepth = 32;
bhttpb.ReaderQuotas.MaxStringContentLength = 8388608;
bhttpb.ReaderQuotas.MaxArrayLength = 16384;
bhttpb.ReaderQuotas.MaxBytesPerRead = 4096;
bhttpb.ReaderQuotas.MaxNameTableCharCount = 16384;
Host = new ServiceHost(DataServer, new Uri[]
{
new Uri("http://localhost:8000")
});
Host.AddServiceEndpoint(typeof(IModelData),
bhttpb,
"ModelData");
Host.Open();
Data = new ArrayList();
}
private void CloseSever()
{
Host.Close();
}
public void UpdateData() // Run on a timer
{
ArrayList Data = new ArrayList()
// Update Data
}
public ArrayList GetData() // This is called by server which is called by client
{
return Data; // no error if I return new ArrayList();
}
}
编辑:问题是否是由于没有 DataContract/DataMembers 引起的?
更新 我已经使用本教程(以及相关教程)从头开始重建了我的新实现:http://blogs.msdn.com/b/brunoterkaly/archive/2013/10/28/wcf-programming-how-to-write-a-client-app-that-connects-to-a-wcf-service.aspx(对于任何感兴趣的人)。
我没有使用 ArrayList(大量拆箱)和 Typed List(如果与 WCF 一起使用,则以数组形式出现),而是选择使用具有以下格式的字符串传递我的数据: "~" 表示列表中新成员的开始 "," 表示我的自定义数据类型中的一种数据类型的结尾。 所以它可能看起来像 "~NAME,1.29,1,4,123.1~NAME,1.23,3,1,13.2" 等。我建议想要使用列表的人改用它。
我的新实现遇到了一个新问题,可能是相同/相似的问题。请看我的新问题:Object reference not set to an instance of an object - WCF Service and Delegates (WCF Hosted before Delegate is instantiated)
感谢大家的帮助。
【问题讨论】:
-
我相信服务器和客户端都有限制。
-
呸!为什么
ArrayList?你真的需要一个任意项目的集合吗? -
@ta.speot.is 是的,我相信上面的代码设置了限制。您是否认为我在此处设置的数据发送过多?我相信这些都设置为最大值
-
在服务器上设置限制,当然。
-
我的“数据”是我自己的数据类型列表,称为“RFData”,它由几个双精度数、整数和一个字符串组成。该列表通常包含其中的 10-30 个。我正在使用 arraylist,因为我比自定义数据类型的类型列表更快地读取它。