WCF RIA服务超时问题

3

我有这样的上下文:

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

使用Silverlight客户端时,我正在发起一个耗时超过1分钟的重型数据库操作。结果,我遇到了超时异常:
未捕获错误:Silverlight应用程序中发生未处理的错误:提交操作失败,对于HTTP请求至 https://localhost/MyProject/ClientBin/myservice.svc/binary 已经超出了允许的时间限制。此操作所分配的时间可能是更长时间限制的一部分。
堆栈跟踪:  在 System.Windows.Ria.OperationBase.Complete(Exception error)  在 System.Windows.Ria.SubmitOperation.Complete(Exception error)  在 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属性。

1个回答

3

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

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属性始终为空。我该怎么办? - Andrei
顺便说一句,我在非公共属性列表中看到它。但是我无法获取它。 - Andrei
channelFactoryProperty 是 null 还是该属性的值为 null? - Spontifixus
我已经成功获取了channelFactoryProperty。现在问题出在GetValue这一行上。我遇到了MethodAccessException。 - Andrei
尝试将GetValue(...)调用的返回值转换为ChannelFactory<LibraryDomainContext.ILibraryDomainServiceContract>,而不仅仅是ChannelFactory...否则我现在就没有更多的想法了 :/ - Spontifixus
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接