[英]Max concurrent sessions for WCF using IIS and Asynch methods - releasing resources
我正在从表单调用WCF服务。 服务托管在IIS中。 具有以下属性的服务:InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple
我已将所有并发调用,实例和会话的限制行为设置为最大2000。
但是我似乎无法收到200多个ASynch请求。 此后,服务只是不响应,会话最终超时。
我正在使用Asynch调用来调用服务中的方法,即Collapse | 复制代码
IASyncResult res = Proxy.BeginMethod(endCall,null);
然后要捕获响应,我有一个endCall函数,该函数接受IASyncResult并通过EndMethod()处理结果。
在每秒调用1次方法的负载模拟中,一切正常,直到大约200次调用,然后等待...(此时我对这200次调用有199或198个响应)..-从理论上讲,不应是200个并发会话,只有2个左右。
也许有一些我没有做的垃圾收集或关闭? 有什么建议么?
----更新---
我认为答案可能更多是因为没有以线程安全的方式处理代理的关闭。 正如Radik指出的那样,关闭代理很重要,但是由于同时出现许多IASyncState结果,因此必须确保在正确的时间关闭正确的代理。
我确实尝试从线程中触发关闭代理,以使其单独处理:
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.