排队服务调用

3
我正在实现一个使用WCF服务的Silverlight应用程序,其中有时会出现多个长时间的服务调用阻塞其他服务调用的情况。
这些服务调用最终会超时。我想看看是否可能实现一个队列系统,按顺序执行服务调用,这样长时间的调用将会阻塞其他调用,但不会导致它们超时。
我正在使用服务代理来包装服务调用。
public interface IExampleServiceAgent
{
    void ProcessData(int a, string b, EventHandler<ProcessDataCompletedEventArgs> callback);
}


Public ExampleServiceAgent1 : IExampleServiceAgent
{
     ExampleClient _Client = new ExampleClient();

     public void ProcessData(int anInt, string aString, EventHandler<ProcessDataCompletedEventArgs> callback)
     {
           EventHandler<ProcessDataCompletedEventArgs> wrapper = null;
           wrapper = (a,b) =>
           {
               callback(a,b);
               _Client.ProcessDataCompleted -= wrapper;
           }
           _Client.ProcessDataCompleted += wrapper;
           _Client.ProcessDataAsync(anInt,aString);
     }
}

上述服务代理将在代码中如下调用:
ServiceAgent.ProcessData(1,"STRING", (a,b) =>
{
    if (b.Error != null)
    {
         //Handle Error
    }
    else
    { 
         //DO something with the data
    }
}

有没有一种方法可以把这些服务调用放入队列中,逐个执行?
我尝试将它们封装为Actions并添加到队列中,但这不会等待一个完成执行后再开始下一个。虽然它们确实正确地调用了服务,但没有数据返回给调用的ViewModel。

相反地,我会关注为什么这些调用需要这么长时间才超时,以及为什么它们会导致其他调用超时。这并不是自然的。 - Aliostad
除了在客户端上添加排队级别外,您是否考虑关闭服务器端WCF服务的一些默认限制?仅当每个IP地址的2个连接限制或MaxConcurrentConnections限制处于默认状态时才会发生阻塞。如果您正在使用多个异步调用访问WCF,则IP地址限制是您首要解决的问题。 - iCollect.it Ltd
一些调用需要处理大量数据,这就是为什么它们需要很长时间的原因。如果我恰好在同一时间收到两个慢速调用,那么其他所有调用在慢速调用完成之前都有很高的超时几率。@HiTechMagic,WCF 中是否有内置队列来防止阻塞? - Midimatt
@Midimatt:WCF不会排队等待调用。它们应该立即执行。任何排队都是为了处理长时间任务而在服务器端执行的。解决方案有两个:1)增加允许的同时连接数;2)停止频繁调用(在客户端进行管理)。 - iCollect.it Ltd
你能分享一下你的 WCF 类的 ServiceBehavior 吗?例如:[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)] - Joel C
显示剩余2条评论
1个回答

3

WCF服务可以处理大量的调用,但为了避免拒绝服务攻击,默认情况下可以处理的请求数量是有限制的。

Silverlight WCF服务的主要限制包括:

  • 来自同一IP地址的同时调用默认限制为2个。
  • 并发连接数量限制在10-16个左右(文档上有所不同)。

这篇CodeProject文章快速提升ASP.NET、WCF和桌面客户端的性能和可扩展性非常有用。

我猜你立即遇到了第一个问题。在你的WCF配置中,你需要添加以下内容以增加单个IP连接数:

<system.net> 
  <connectionManagement> 
    <add address="*" maxconnection="100" /> 
  </connectionManagement> 
</system.net>

你可能会遇到第二个限制,解决方案是在web/app.config文件中调整服务行为。以下是我在自己解决这些问题时找到的一些参考资料:

增加最大连接数已经停止了超时,这太好了,我得阅读那些文章,看看是否有其他我可以使用的技巧。谢谢。 - Midimatt

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