关于在ASP.NET中并行执行.NETHttpWebRequests的建议服务电话。我有一个场景,我正在对两个单独的服务进行两次HttpWebRequest调用。我需要他们两个来完成延续,但他们的顺序无关紧要。它们每个可能需要1-2秒,我现在按顺序运行它们。并行运行会减少用户响应时间,但最好的方法是什么?在研究这个问题时,我可以想到几个选项:我需要找到一个可以大规模工作的解决方案。这就是为什么我担心线程池的大小。我不愿意阻止请求,因为它们正在等待可用的线程。我喜欢手动执行此类操作,而不是依赖异步Web请求或线程池的自动调整大小(默认为25个线程)。当然,这些都是问题的完美解决方案,但我认为下面的代码更具可读性(在下面的示例中,_links将包含处理前的链接列表......):privatestaticIList_links=newList();私人常量intNumberOfThreads=2;publicvoidSpawnWebRequests(){IListthreadList=newList();for(inti=0;i如果您只想管理线程池大小(如果您使用的是ThreadPool.QueueUserWorkItem()),那么您可以使用ThreadPool.SetMaxThreads=2)。当然,如果你想使用微软认可的异步方法,看看这个例子:http://msdn.microsoft.com/en-us/library/86wf6409.aspx。只要确保清理每个响应(通过“使用”块或关闭响应对象)!希望有帮助,Noah多线程WebRequests的答案,一个好的和稳定的方法?:CSharp控制event.Set()withManualResetEventevent=newManualResetEvent(),一个引用计数器等于飞行中请求的数量和Interlocked.Decrement。然后主线程通过调用event.WaitOne()等待。但是,WaitHandles-Auto/ManualResetEvent和Mutex提到ManualResetEvent“可能比使用Wait、Pulse和PulseAll等各种监视器方法慢得多。我最终从NoahBlumenthal博客文章中删除了我的代码:RunningGenericTaskasync(fluent).我做了两个更改:实现IDisposable并在ManualResetEvent上调用.Close()以及从使用lock()切换到Interlocked.Decrement()和.Decrement()。公共类AsyncQueueManager:IDisposable{privatereadonlyManualResetEventwaitHandle=newManualResetEvent(true);私人整数计数=0;publicAsyncQueueManagerQueue(Actionaction){Interlocked.Increment(refcount);行动);WaitCallbackwaitCallback=newWaitCallback(actionWrapper);ThreadPool.QueueUserWorkItem(waitCallback);归还这个;}privateActionCreateActionWrapper(Actionaction){ActionactionWrapper=(objectstate)=>{tryatch{action(state);(Exceptionex){//log}finally{if(Interlocked.Decrement(refcount)==0){waitHandle.放();}}};返回动作包装器;}publicvoidWait(){waitHandle.等待一个();}publicvoidWait(TimeSpantimeout){waitHandle.WaitOne(timeout);}publicvoidDispose(){waitHandle.Close();我建议你创建一个执行HttpWebRequest的工作类,并在每个连接自己的线程中启动它。您可以加入线程并等待它们全部完成,或者传递回调方法。无论哪种情况,您都需要考虑连接失败、超时和其他异常。我更喜欢使用返回连接结果和线程的ManagedThreadId的回调,我用它来跟踪线程。工作类应该捕获所有异常,以便您可以在调用类中处理它们。本文针对超过最大连接数提供了一些见解和修复:http://support.microsoft.com/kb/821268。除非您正在做一些花哨的事情,否则ThreadPool具有固定大小并且通常足够大以满足您的需要。在您的特定情况下,如果您的Web服务负载很重并且每个调用者都为自己的回调启动了2个TP线程,则您可能会遇到使用AsyncIO调用的资源约束问题。也许最简单的实现可能是在每个CompletionEvents中有两个不同的回调函数,一个用于service1,一个用于service2,将一些触发变量设置为“true”,然后在主线程设置中等待两个触发变量。您可以使用ResetEvents执行此操作,但如果您的服务器负载不足,您可能希望避免此操作。该过程的伪代码可能是:DictionarycallCompleted=newDictionarystringoperation1Key=Guid.NewGuid().ToString();stringoperation2Key=Guid.NewGuid().ToString();callCompleted[operation1Key]=false;callCompleted[operation2Key]=false;//进行远程调用并将操作键作为数据传递//....//...boolwaiting=true;while(waiting){boolisFinished=true;foreach(stringoperationKeyincallCompleted.Keys){isFinished&=callCompleted[operationKey]if(!isFinished){break;}}waiting=!isFinished;}因为我不知道你打电话的确切性质,所以有点激动,但它应该工作得相当好。以上就是《C#学习教程:ASP.NET中并行执行.NETHttpWebRequests》的全部内容。代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
