C# 基础连接已关闭:连接意外关闭。数据太大?

C# 基础连接已关闭:连接意外关闭。数据太大?,c#,wcf,C#,Wcf,我有一个服务器/客户机关系,客户机从服务器中提取ArrayList。如果我将服务器设置为始终发送空的ArrayList,则不会出现此错误。很明显,问题是我的数据太大,无法连接,而且在所有数据都能通过之前就已经关闭了 我已经研究过这个问题,并添加了此问题/答案建议的功能: 许多解决方案都提出了同样的问题 我认为我实现了一些错误的东西(我认为很可能是服务行为MaxItemsInObjectGraph,因为我仍然会遇到同样的错误。不幸的是,我无法找出它的错误。以下是我的代码: 我收到的错误是: Com

我有一个服务器/客户机关系,客户机从服务器中提取ArrayList。如果我将服务器设置为始终发送空的ArrayList,则不会出现此错误。很明显,问题是我的数据太大,无法连接,而且在所有数据都能通过之前就已经关闭了

我已经研究过这个问题,并添加了此问题/答案建议的功能: 许多解决方案都提出了同样的问题

我认为我实现了一些错误的东西(我认为很可能是服务行为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引起

更新 我已经使用本教程(以及相关教程)从头开始重新构建了我的新实现:(适合感兴趣的人)

我没有使用ArrayList(大量取消装箱)和类型化列表(如果与WCF一起使用,则显示为数组),而是选择使用以下格式的字符串传递数据: “~”表示列表中新成员的开始 “,”表示自定义数据类型中某个数据类型的结尾。 所以它可能看起来像“~NAME,1.29,1,4123.1~NAME,1.23,3,1,13.2”等等。我建议想要使用列表的人使用这个

我的新实现遇到了新问题,可能是相同/类似的问题。请查看我的新问题:


谢谢大家的帮助。

客户端配置为什么?您已经显示了服务器端配置,但不要忘记客户端有自己的配置设置

查看服务器端配置,似乎在客户端接收数据时发生了冲突

有关示例,请参见。您也可以通过编程方式执行此操作

编辑

现在我在评论中看到,您从服务器获得的这个
ArrayList
包含您自己的用户定义类型
RFData
。我现在相信这可能是您问题的根源

数据协定描述正在交换的数据。数据协定在客户端和服务器之间用于对通过线路发送的数据进行序列化和反序列化。在定义自己要在WCF模型中使用的类型时,需要使用数据协定/数据成员。基元以及许多内置的.NET类型他们已经有了数据合同

对于您的
RFData
类型,它将如下所示:

// Apply the DataContract to the type
[DataContract]
public class RFData
{
    // Apply the DataMemberAttribute to the various properties
    [DataMember]
    public double RFDouble { get; set; }
    [DataMember]
    public int RFInt { get; set; }
    [DataMember]
    public string RFString { get; set; }
}

我知道你有几个整数和双精度,但你明白了要点。这是MSDN关于数据契约的一个非常有用的指南。

我相信服务器和客户端都有限制。哎呀!为什么
ArrayList
?你真的需要一个任意项的集合吗?@ta.speot。是的,我相信上面的代码设置了限制。你认为我也在发送吗我在这里设置的数据太多了?我相信这些都设置为最大值设置了服务器上的限制,当然。我的“数据”是我自己的数据类型列表,称为“RFData”,它由几个双精度、整数和1个字符串组成。该列表通常包含其中的10-30个。我使用arraylist是因为我读取自定义数据类型的列表比键入的列表快。嗨,德里克,谢谢你的帮助。我的项目中没有app.config文件。有其他方法检索此配置文件吗?@Watson,你应该说清楚您的客户端/服务器项目类型是什么。
app.config
仅在某些项目中可用。对于其他项目,您应该查看
web.config
servicerences.clientconfig
。如果您的客户端项目是WinForms项目,您可以创建
app.config
,如果它还不在项目中。感谢您的帮助ek,我真的很感激。请看我帖子底部的“更新”。@DerekW看到上面的评论(忘记标记)