当我返回ObservableCollection时,为什么会出现此超时错误?

时间:2012-05-16 21:53:41

标签: c# asp.net silverlight

我有一个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 个答案:

答案 0 :(得分:1)

有几种可能性:

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

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

  3. 您可以更改客户端超时。

       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);
        }
      }
    }
    

    来源:Kyle McClennan [MSFT]

答案 1 :(得分:1)

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

同时发布你的web.config可能有所帮助。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

问题实际上是一些数据。某些列中存在DBNull值,这在反序列化过程中会造成问题。它抛出的错误消息刚刚完全关闭。

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

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