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

发布于 2024-12-05 14:57:23 字数 785 浏览 4 评论 0原文

我正在从表单调用 WCF 服务。服务托管在 IIS 中。该服务具有以下属性: InstanceContextMode.PerSession、ConcurrencyMode = ConcurrencyMode.Multiple

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

但是我似乎无法收到超过 200 个异步请求。此后,服务不再响应,会话最终超时。

我正在使用异步调用来调用服务中的方法,即 折叠 |语言:

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

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

在负载模拟中,每秒调用 1 个方法,一切正常,直到大约 200 个调用,然后只需等待...(此时我从这 200 个调用中得到了 199 或 198 个响应).. - 所以理论上是存在的不应该是 200 个并发会话,只有 2 个左右。

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

----更新---

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

我确实尝试从线程中关闭关闭代理,让它单独处理它:

ThreadPool.QueueUserWorkItem(CloseProxy, ar.AsyncState);

但这似乎不起作用。对此有何建议?

I am calling a WCF service from a form. Service is hosted in IIS. The service with the following attributes: InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple

I have set the throttling behaviour to max out at 2000 for all concurrent calls, instances and sessions.

However I cant seem to get more than 200 ASynch requests. After that the service just does not respond, and the session eventually times out.

I am using an Asynch call to call the method in the service ie
Collapse | Copy Code

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

and then to catch the response I have a endCall function that takes in the IASyncResult and processes the result via EndMethod().

in a load simulation @ 1 method call a second, it all works fine until around 200 calls, and then just waits... (I have 199 or 198 responses from those 200 calls at this point in time).. - so theoretically there should NOT be 200 concurrent sessions just 2 or so..

Perhaps there is some garbage collection or closing that I am not doing?
any suggestions?

----update---

I think the answer maybe more that the closing of the proxy is not handled in a thread safe way. As Radik points out above, closing the proxy is important however with many IASyncState results coming in simultaneously you have to make sure you close the right one at the right time.

I did try firing off the close proxy from a thread to let it handle it seperately:

ThreadPool.QueueUserWorkItem(CloseProxy, ar.AsyncState);

but that does not seem to work. Any suggestions on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉月流沐 2024-12-12 14:57:23

当您在 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);
}

When you create service reference in VS, generated proxy allow you asynchronously call service by two ways with callback or event handler. And two different places where you can close proxy.
little sample project here

//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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文