25个使用任务进行编排的并发异步WCF调用
我有一个应用程序(.NET 4.0),它在启动时加载管理数据。我必须进行25次并发异步WCF调用,其中一些调用速度很快(40毫秒),另一些调用执行时间较长,高达882毫秒。我计划在本地存储数据,但对于第一次应用程序启动,需要尽快完成 应该注意的是,代理位于以.NET 3.5为目标的库中,并且在Jeffrey Richter的异步枚举器的帮助下,在内部使用封装到异步方法中的BeginXxx和EndXxx方法模式 将要使用的每个客户端代理的WCF通道工厂将在启动调用之前打开 此时,我正在使用Task.Factory.StartNew和启动每个异步调用的操作。经验如下:25个使用任务进行编排的并发异步WCF调用,wcf,c#-4.0,task,Wcf,C# 4.0,Task,我有一个应用程序(.NET 4.0),它在启动时加载管理数据。我必须进行25次并发异步WCF调用,其中一些调用速度很快(40毫秒),另一些调用执行时间较长,高达882毫秒。我计划在本地存储数据,但对于第一次应用程序启动,需要尽快完成 应该注意的是,代理位于以.NET 3.5为目标的库中,并且在Jeffrey Richter的异步枚举器的帮助下,在内部使用封装到异步方法中的BeginXxx和EndXxx方法模式 将要使用的每个客户端代理的WCF通道工厂将在启动调用之前打开 此时,我正在使用Task
<netTcpBinding>
<binding transactionFlow="true" listenBacklog="500" maxReceivedMessageSize="400000"
portSharingEnabled="false">
<readerQuotas maxDepth="200" />
<reliableSession enabled="false" />
<security mode="None">
<transport clientCredentialType="None" protectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
<service name="AdminService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="IAdmin">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
</service>
编辑3:以下是使用J.Richter的AsyncEnumerator的代码:
private IEnumerator<int> DoWorkGetXXXX(AsyncEnumerator<MyResult> ae)
{
ae.ThrowOnMissingDiscardGroup(true);
IClientChannel proxy = (IClientChannel)CreateChannel(_bindingName);
bool success = false;
try
{
proxy.Open();
// The call to BeginXXX goes here
((IAcaccount)proxy).BeginGetXXX(..., ae.EndVoid(0, DiscardGetXXX), proxy);
//
yield return 1;
if (ae.IsCanceled())
{
goto Complete;
}
// Iterator was not canceled, process should continue.
// The call to EndXXX goes here
IAsyncResult ar = ae.DequeueAsyncResult();
try
{
ae.Result = ((IAcaccount)ar.AsyncState).EndGetXXX(ar);
proxy.Close();
success = true;
}
// In the mean time, we catch and rethrow :)
// If this exception occurs, we should retry a call to the service
catch (FaultException<AppFabricCachingException> retry)
{
}
// fatal Exception in data service, administrator action required...
catch (FaultException<EFExecutionException> fatal)
{
}
catch (FaultException<EFUpdateException> fatal)
{
}
catch (FaultException<EFNoRowException> nr)
{
}
catch (FaultException fe)
{
}
catch (ServiceActivationException sae)
{
}
catch (CommunicationException ce)
{
}
//
}
finally
{
// If an error occurred, abort the proxy.
if (!success)
{
proxy.Abort();
}
}
// End of operations.
Complete:
proxy = null;
}
私有IEnumerator DoWorkGetXXXX(异步枚举器ae)
{
ae.ThrowonMissingDiscard组(真);
IClientChannel代理=(IClientChannel)CreateChannel(_bindingName);
布尔成功=假;
尝试
{
proxy.Open();
//对BeginXXX的调用转到这里
((iaccount)proxy.BeginGetXXX(…,ae.EndVoid(0,DiscardGetXXX),proxy);
//
收益率1;
if(ae.IsCanceled())
{
去完成;
}
//迭代器未取消,进程应继续。
//对EndXXX的调用转到这里
IAsyncResult ar=ae.DequeueAsyncResult();
尝试
{
ae.Result=((iaccount)ar.AsyncState).EndGetXXX(ar);
proxy.Close();
成功=真实;
}
//同时,我们捕获并重新捕获:)
//如果发生此异常,我们应该重试对服务的调用
捕获(FaultException重试)
{
}
//数据服务中出现致命异常,需要管理员操作。。。
捕获(FaultException致命)
{
}
捕获(FaultException致命)
{
}
捕获(错误异常编号)
{
}
捕获(故障异常fe)
{
}
捕获(服务激活异常sae)
{
}
捕获(通信异常ce)
{
}
//
}
最后
{
//如果发生错误,请中止代理。
如果(!成功)
{
proxy.Abort();
}
}
//行动结束。
完成:
proxy=null;
}
您可以尝试使用serviceThrottling的值,以及maxItemsInObjectGraph、maxBufferSize、MaxBufferPoolSize(我已将它们设置为int.MaxValue)。这可能有帮助,可能是连接问题您的绑定是什么?服务器配置?您可以发布服务器配置吗?@JohnField我已经编辑了我的问题,我正在使用netTcpBinding@evgenyl我已经用请求的信息编辑了我的问题。您是否尝试放大限制值?
private IEnumerator<int> DoWorkGetXXXX(AsyncEnumerator<MyResult> ae)
{
ae.ThrowOnMissingDiscardGroup(true);
IClientChannel proxy = (IClientChannel)CreateChannel(_bindingName);
bool success = false;
try
{
proxy.Open();
// The call to BeginXXX goes here
((IAcaccount)proxy).BeginGetXXX(..., ae.EndVoid(0, DiscardGetXXX), proxy);
//
yield return 1;
if (ae.IsCanceled())
{
goto Complete;
}
// Iterator was not canceled, process should continue.
// The call to EndXXX goes here
IAsyncResult ar = ae.DequeueAsyncResult();
try
{
ae.Result = ((IAcaccount)ar.AsyncState).EndGetXXX(ar);
proxy.Close();
success = true;
}
// In the mean time, we catch and rethrow :)
// If this exception occurs, we should retry a call to the service
catch (FaultException<AppFabricCachingException> retry)
{
}
// fatal Exception in data service, administrator action required...
catch (FaultException<EFExecutionException> fatal)
{
}
catch (FaultException<EFUpdateException> fatal)
{
}
catch (FaultException<EFNoRowException> nr)
{
}
catch (FaultException fe)
{
}
catch (ServiceActivationException sae)
{
}
catch (CommunicationException ce)
{
}
//
}
finally
{
// If an error occurred, abort the proxy.
if (!success)
{
proxy.Abort();
}
}
// End of operations.
Complete:
proxy = null;
}