0

我有一个 Silverlight 应用程序,它正在从我的网站上的服务中获取项目列表。我将它作为具有以下功能的 ObservableCollection 传递:

public ObservableCollection<Dictionary<string, object>> GetItems(string transetDocId)
    {
                    ObservableCollection<Dictionary<string, object>> result = new ObservableCollection<Dictionary<string, object>>();
            foreach (DataRow dr in ((DataTable)HttpContext.Current.Session["ItemDataTable"]).Rows)
            {
                Dictionary<string, object> tempD = new Dictionary<string, object>();
                foreach (DataColumn dc in ((DataTable)HttpContext.Current.Session["ItemDataTable"]).Columns)
                    tempD.Add(dc.ColumnName, dr[dc.ColumnName]);
                result.Add(tempD);
            }
            return result;
        }

一切正常现在,没有我能想到的任何更改,它已经开始返回以下错误。

对“http://www.example.com/Services/Example.svc”的 HTTP 请求已超过分配的超时。分配给此操作的时间可能是较长超时的一部分。

我已经逐步完成了代码。我正在客户端中启动 GetItemsAsync() 方法。服务看到调用,创建结果并返回它。但是 GetChecksCompleted() 方法永远不会被命中(是的,我正在添加一个事件处理程序)。几分钟后,我得到了错误。

我尝试修改代码,使其返回一个长逗号/分号/管道分隔的字符串,而不是一个可观察的集合,并且一切运行正常。

为什么 ObservableCollection 不起作用?

更多信息:我得到的错误实际上发生在 return 语句之前的行中生成的文件 Reference.cs 中:

public System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>> EndGetItems(System.IAsyncResult result) {
                object[] _args = new object[0];
                System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>> _result = ((System.Collections.ObjectModel.ObservableCollection<System.Collections.Generic.Dictionary<string, object>>)(base.EndInvoke("GetItems", _args, result)));
                return _result;
            }
4

4 回答 4

2

我认为当返回数据的大小超过大小限制时可能会发生这种情况。尝试只返回一个元素而不是所有列表,以确保它不是原因。如果是 - 在配置文件中设置所需的 maxBufferSize。

还发布您的 web.config 可能会有所帮助。

于 2012-05-30T08:48:03.127 回答
1

有几种可能性:

  1. 也许您有太多数据要返回。在服务器端放一个断点,看看你有多少行。

  2. 您实际上不必返回 ObservableCollection。WCF 将返回一个列表,由您的客户端将其转换为 ObservableCollection。

您可以更改客户端超时。

   using System.ServiceModel.DomainServices.Client;

   /// <summary>
   /// Utility class for changing a domain context's WCF endpoint's
   /// SendTimeout. 
   /// </summary>
   public static class WcfTimeoutUtility
   {
    /// <summary>
    /// Changes the WCF endpoint SendTimeout for the specified domain
    /// context. 
    /// </summary>
    /// <param name="context">The domain context to modify.</param>
    /// <param name="sendTimeout">The new timeout value.</param>
    public static void ChangeWcfSendTimeout(DomainContext context, 
                                            TimeSpan sendTimeout)
    {
      PropertyInfo channelFactoryProperty =
        context.DomainClient.GetType().GetProperty("ChannelFactory");
      if (channelFactoryProperty == null)
      {
        throw new InvalidOperationException(
          "There is no 'ChannelFactory' property on the DomainClient.");
      }

      ChannelFactory factory = (ChannelFactory)
        channelFactoryProperty.GetValue(context.DomainClient, null);
      factory.Endpoint.Binding.SendTimeout = sendTimeout;
    }
   }

将长时间运行的操作的域上下文和发送超时的新值传递给 ChangeWcfSendTimeout 方法,这样就很好了。使用终结点后无法更改绑定,因此调用此方法的最佳位置是在域上下文的部分 OnCreated 方法中,如下所示:

namespace SampleNamespace.Web.Services
{
  public partial class MyDomainContext
  {
    partial void OnCreated()
    {
      TimeSpan tenMinutes = new TimeSpan(0, 10, 0);
      WcfTimeoutUtility.ChangeWcfSendTimeout(this, tenMinutes);
    }
  }
}

资料来源:凯尔麦克伦南 [MSFT]

于 2012-05-17T06:20:49.440 回答
0

问题实际上出在一些数据上。一些列中有一个 DBNull 值,这在反序列化过程中造成了麻烦。它抛出的错误消息完全关闭。

在启用跟踪后,我能够弄清楚发生了什么,如下所述:http: //msdn.microsoft.com/en-us/library/ms733025.aspx

感谢 anatoliiG 让我朝着正确的方向前进。

于 2012-05-31T15:25:19.150 回答
0

我想你必须处理你的客户端连接。有连接数量有限的连接池。我记得当所有连接都在使用时,建立新连接的尝试失败。只需将您的频道包装为“使用”声明即可。

于 2012-05-30T06:39:07.193 回答