使用IIS和异步方法的WCF最大并发会话-释放资源

本文关键字:并发 会话 释放资源 WCF IIS 异步方法 使用 | 更新日期: 2023-09-27 18:08:58

我正在从表单调用WCF服务。服务托管在IIS中。具有以下属性的服务:InstanceContextMode。PerSession, ConcurrencyMode = ConcurrencyMode。多个

我已经将所有并发调用、实例和会话的节流行为设置为最大2000。

然而,我似乎不能得到超过200异步请求。在此之后,服务不再响应,并且会话最终超时。

我使用异步调用来调用服务ie中的方法崩溃|复制代码

IASyncResult res= Proxy.BeginMethod(endCall,null);

然后捕获响应,我有一个endCall函数,它接受IASyncResult并通过EndMethod()处理结果。

在加载模拟@ 1方法调用一秒钟,它都工作得很好,直到大约200个调用,然后只是等待…(在这200个电话中,我有199或198个回复)……所以理论上不应该有200个并发会话,只要2个左右就可以了。

也许有一些垃圾收集或关闭,我没有做?有什么建议吗?

——更新

我认为答案可能更多的是关闭代理不是以线程安全的方式处理的。正如Radik上面所指出的,关闭代理是很重要的,但是随着许多IASyncState结果同时出现,你必须确保在正确的时间关闭正确的代理。

我确实尝试过从线程中触发close代理,让它单独处理它:

ThreadPool。QueueUserWorkItem (CloseProxy ar.AsyncState);

,但这似乎不起作用。对此有什么建议吗?

使用IIS和异步方法的WCF最大并发会话-释放资源

当您在VS中创建服务引用时,生成的代理允许您通过回调或事件处理程序两种方式异步调用服务。还有两个不同的地方可以关闭代理。这里有一个小示例项目

//close proxy in callback function
private void ButtonCallbackClick(object sender, EventArgs e)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.BeginDoWork(DateTime.Now.ToShortDateString(), CallBack, proxy);
}
private void CallBack(IAsyncResult ar)
{
    var result = (ar.AsyncState as ServiceClient).EndDoWork(ar);
    if (ar.IsCompleted)
        UpdateView(result);
    CloseProxy(ar.AsyncState);
}
//close proxy in event handler
private void ButtonCompletedClick(object sender, EventArgs e)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.DoWorkAsync(DateTime.Now.ToShortDateString());
    proxy.DoWorkCompleted += DoWorkCompleted;
}
private void DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
{
    if (e.Error == null)
        UpdateView(e.Result);
    CloseProxy(sender);
}
private static void CloseProxy(object sender)
{
    var proxy = sender as ServiceClient;
    if (proxy == null) return;
    try
    {
        proxy.Close();
    }
    catch (CommunicationException e)
    {
        proxy.Abort();
    }
    catch (TimeoutException e)
    {
        proxy.Abort();
    }
    catch (Exception e)
    {
        proxy.Abort();
    }
}
private static bool _run = false;
//run async query in infinite cycle
private void ButtonCycleClick(object sender, EventArgs e)
{
    _run = !_run;
    if (!_run) return;
    Action<object> action = WaitEvent;
    ThreadPool.QueueUserWorkItem(a => action(action));
}
private void WaitEvent(object action)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    proxy.DoWorkAsync(DateTime.Now.ToShortDateString());
    proxy.DoWorkCompleted += (x, y) => DoWorkCompleted(x, y, action as Action<object>);
}
private void DoWorkCompleted(object sender, DoWorkCompletedEventArgs e, Action<object> action)
{
    if (!_run)
        return;
    if (e.Error == null)
        UpdateView(e.Result);
    CloseProxy(sender);
    action(action);
}