【问题标题】:WCF RIA Service timeoutWCF RIA 服务超时
【发布时间】:2013-05-12 11:09:42
【问题描述】:

我有这样的背景:

[EnableClientAccess()]
public class MyRiaService : LinqToEntitiesDomainService<EntityFrameworkContext>

我使用 Silverlight 客户端启动繁重的数据库操作,这需要超过 1 分钟。结果我得到了超时异常:

未捕获的错误:Silverlight 应用程序中出现未处理的错误: 提交操作失败。对https://localhost/MyProject/ClientBin/myservice.svc/binary 的 HTTP 请求已超过分配的超时。分配给此操作的时间可能是较长超时的一部分。

堆栈跟踪:
在 System.Windows.Ria.OperationBase.Complete(异常错误)
在 System.Windows.Ria.SubmitOperation.Complete(异常错误)
在 System.Windows.Ria.DomainContext.CompleteSubmitChanges(IAsyncResult asyncResult)
在 System.Windows.Ria.DomainContext.c_DisplayClassd.b_5(Object )

我很乐意在那里更改发送超时,但我不知道如何更改。 我试过这个:

((WebDomainClient<LibraryDomainContext.ILibraryDomainServiceContract>)this.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);

但我没有属性 DomainClient

【问题讨论】:

    标签: c# silverlight silverlight-3.0 wcf-ria-services


    【解决方案1】:

    连接的超时时间可以在域服务端点的客户端设置。但是如何掌握呢?通过为域上下文创建扩展方法:

    public static class DomainServiceExtensions
    {
        /// <summary>
        /// This method changes the send timeout for the specified 
        /// <see cref="DomainContext"/> to the specifified <see cref="TimeSpan"/>.
        /// </summary>
        /// <param name="domainContext">
        /// The <see cref="DomainContext"/> that is to be modified.
        /// </param>
        /// <param name="newTimeout">The new timeout value.</param>
        public static void ChangeTimeout(this DomainContext domainContext, 
                                              TimeSpan newTimeout)
        {
            // Try to get the channel factory property from the domain client 
            // of the domain context. In case that this property does not exist
            // we throw an invalid operation exception.
            var channelFactoryProperty = domainContext.DomainClient.GetType().GetProperty("ChannelFactory");
            if(channelFactoryProperty == null)
            {
                throw new InvalidOperationException("The 'ChannelFactory' property on the DomainClient does not exist.");
            }
    
            // Now get the channel factory from the domain client and set the
            // new timeout to the binding of the service endpoint.
            var factory = (ChannelFactory)channelFactoryProperty.GetValue(domainContext.DomainClient, null);
            factory.Endpoint.Binding.SendTimeout = newTimeout;
        }
    }
    

    有趣的问题是何时调用此方法。一旦端点在使用中,就不能再更改超时。所以在创建域上下文后立即设置超时:

    DomainContext 类本身是 sealed,但幸运的是,该类也被标记为 partial - 就像方法 OnCreated() 一样,可以通过这种方式轻松扩展。

    public partial class MyDomainContext
    {
        partial void OnCreated()
        {
            this.ChangeTimeout(new TimeSpan(0,10,0));
        }
    }
    

    专业提示:当实现部分类时,类的所有部分的命名空间必须相同。此处列出的代码属于客户端项目(例如使用命名空间RIAServicesExample),但上面显示的部分类需要驻留在服务器端命名空间中(例如RIAServicesExample.Web)。

    【讨论】:

    • 使用这种方法,我的 ChannelFactory 属性始终为空。我能用它做什么?
    • 顺便说一句,我在非公共财产列表中看到了它。但我无法得到它
    • channelFactoryProperty 为空还是该属性的值为空?
    • 我设法获得了 channelFactoryProperty。现在问题出在 GetValue 行上。我得到 MethodAccessException
    • 尝试将GetValue(...) 调用的返回值转换为ChannelFactory&lt;LibraryDomainContext.ILibraryDomainServiceContract&gt; 而不仅仅是ChannelFactory... - 否则我现在没有想法了:/
    猜你喜欢
    • 2011-01-14
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    相关资源
    最近更新 更多