使用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);
,但这似乎不起作用。对此有什么建议吗?
当您在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);
}