【问题标题】:SQL-Server access with WCF: Timeout使用 WCF 访问 SQL-Server:超时
【发布时间】:2010-11-21 06:44:52
【问题描述】:

我有一台带有 SQL2008 数据库和 IIS7 的服务器。我创建了一个 WCF 服务,它访问 SQL-Server 并以 List<T> 的形式返回结果集。

我的问题是,我在从客户端访问服务时遇到超时,尽管查询不应该花费太长时间(在 SQL 管理器中大约 1 秒)它会获取 17.256 行。

当我将查询限制为只读取十几行时,它运行良好:

SqlCommand command = new SqlCommand("SELECT stammDatenId, position, latitude, longitude FROM geoKoordinates ORDER BY stammDatenId, position", connection);
IDataReader reader = command.ExecuteReader();
int count = 0;

while (reader.Read())
{
    GeoKoordinates geoKoors = new GeoKoordinates();
    geoKoors.stammDatenId = reader.GetInt32(0);
    geoKoors.position = reader.GetInt32(1);
    geoKoors.latitude = reader.GetDouble(2);
    geoKoors.longitude = reader.GetDouble(3);

    resultSet.Add(geoKoors);
    if (count > 10)
        break;

    count++;
}
reader.Close();

但正如您可能猜到的那样,我需要所有 17k 行。网络连接速度应该不是问题,因为服务器和我的客户端都在我们的局域网内,有 100 MBit 线路。从 SQL-Manager 将结果集保存到 csv 时,它只有 600 kb 大。

知道瓶颈可能在哪里以及如何解决这个问题吗?我不知道,代码的哪一部分可能与回答这个问题有关。如果您需要看一些特殊的部分,请在此处注明,我会提供。

【问题讨论】:

  • 我试图将调用 WCF 的代码放在同一台服务器上,但是我得到了一个非常烦人的 CommunicationException: NotFound。没有单词 WHAT wcf not found 或 WHERE。无论如何要调试这个或获得有意义的错误消息?反正今天太热了,我的脉搏已经180了。我想我会休息一下,明天继续。感谢我在这里得到的所有帮助!

标签: c# sql-server wcf


【解决方案1】:

什么样的超时?

你可能有:

  • SQL 超时。检查 SqlConnection/DataContext 上的 CommandTimeout
  • 事务超时,为您自己的 TransactionScopes 设置 TransacitonOptions.Timeout 或将以下 WCF 服务器的配置放在相关行为下
<serviceTimeouts transactionTimeout="00:10:00"/>
  • 或者它是 WCF 超时,这很可能是最有可能的,因为您会将所有数据转换为 XML,并且这些默认为 1 分钟。建议在客户端绑定上设置receiveTimeout。正如 marc_s 所说,您可能会遇到基于数据大小的其他问题(但不是超时),下面也有这样的示例:

<wsHttpBinding>
  <binding name="PcsInterfaceSecureBinding" openTimeout="00:10:00" receiveTimeout="00:10:00"
   sendTimeout="00:10:00" maxBufferPoolSize="8000000" maxReceivedMessageSize="2147483647">
    <readerQuotas maxDepth="32" maxStringContentLength="65536000"
     maxArrayLength="2147483647" maxBytesPerRead="8192" maxNameTableCharCount="16384" />
    <security mode="Transport" />
  </binding>
</wsHttpBinding>

【讨论】:

  • 我不明白为什么我的后一个 XML 不会出现!所以我放弃了,但属性在 元素上。感谢一个模组是否可以解决这个问题,因为我不知道为什么 不显示它
  • @MattH:如果您在项目符号后添加一段代码,这似乎是个问题 - 我添加了一个空行,一行只有一个“。”和另一个空行使其工作......
  • 谢谢马克 - 奇怪。下次我可能会避免使用要点语法
  • 这是一个 System.TimeoutException,在 InternalEndGetResponse(...) 有两个级联 System.Net.WebException 内部异常。
【解决方案2】:

这里有一件小事可能会使您的结果复杂化。你应该实现using 块:

using (SqlCommand command = new SqlCommand(
   "SELECT stammDatenId, position, latitude, longitude "+
   "FROM geoKoordinates ORDER BY stammDatenId, position", connection))
{
    using (IDataReader reader = command.ExecuteReader())
    {
        // ...
    }
}

【讨论】:

  • 据我所知 using 将读者的范围设置为 using 语句之后的花括号。有什么理由(除了编码风格)使用 using?
  • using 应该在您创建实现IDisoposable 接口的类的实例时使用。它确保Dispose 方法被调用,即使出现异常。
  • 啊,我不知道。感谢您的信息!
【解决方案3】:

增加绑定配置文件中的超时时间。检查错误是否仍然出现。请参阅this 链接。可能会有所帮助。

【讨论】:

    【解决方案4】:

    您可能遇到的问题不是超时,而是默认 WCF 消息大小不够大。

    默认情况下,WCF 限制为 64K 消息 - 可能有 17K 行,这已经太多了 - 听起来就像你写的那样。

    您可以通过多种设置来增加这些消息的大小 - 其中大部分设置在您的绑定中。这些将是:

    • maxBufferPoolSize
    • 最大缓冲区大小
    • maxReceivedMessageSize

    例如配置值wsHttpBinding,使用这个片段:

    <bindings>
      <wsHttpBinding>
        <binding name="LargeWsHttp"
                 maxBufferSize="512000"
                 maxBufferPoolSize="512000"
                 maxReceivedMessageSize="512000" />
      </wsHttpBinding>
    

    然后只需在您的端点(客户端和服务器端!)中引用该绑定:

    <endpoint address="......"
              binding="wsHttpBinding" 
              bindingConfiguration="LargeWsHttp" 
              contract="......" />
    

    &lt;ReaderQuotas&gt; 上的其他设置(作为绑定中的子标签)- 包括:

    • 最大字符串内容长度
    • 最大数组长度
    • maxBytesPerRead
    • maxNameTableCharCount

    这些 - 正如名称“读者配额”所暗示的那样,可能在服务器接收消息时与服务器更相关。

    马克

    【讨论】:

    • 不支持 maxBufferPoolSize 作为客户端 ServiceReferences.ClientConfig 文件中的属性。无论如何,客户端已经有一个基本的HttpBinding(因为 Silverlight,我使用的是基本的),并且数量足够大(2147483647)。我在服务器端包含了您的绑定,使用 2147483647 作为值。我仍然遇到超时,但它只是在大约 45 秒后发生。
    • 在我打破 while 循环后,我对行数进行了一些调整。结果是,用 13k 行我几乎立即得到结果,而用 13.5k 行,它会超时(45 秒后)。所以它似乎与返回结果的大小有关。我在服务器端使用了您的 bindingConfiguration,在客户端使用了标准的大型绑定配置,但问题似乎出在其他地方
    【解决方案5】:

    不要返回 17,000 行。翻阅它们。这也将允许客户端在 SQL 执行其操作并从数据库获取更多数据时开始处理。

    【讨论】:

    • 奇怪的是,13k 行来得非常快,但是 >13.5k 行却超时了。
    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多