考虑这个问题:我有一个程序应该从数据库中获取(比如说)100条记录,然后对于每一条记录,它应该从Web服务获取更新的信息.在这种情况下,有两种方法可以引入并行性:
我在新线程上启动对Web服务的每个请求.同时线程的数量由一些外部参数控制(或以某种方式动态调整).
我创建了较小的批次(假设每个都有10个记录),并在一个单独的线程上启动每个批处理(所以以我们的例子为例,10个线程).
哪种方法比较好,为什么这么认为呢?
选项3是最好的:
使用Async IO.
除非您的请求处理复杂且繁重,否则您的程序将花费99%的时间等待HTTP请求.
这正是Async IO的设计目标 - 让Windows网络堆栈(或.net框架或其他)担心所有等待,只需使用一个线程来调度和"拾取"结果.
不幸的是,.NET框架使它成为一个正确的痛苦.如果你只是使用原始套接字或Win32 api,这会更容易.这是一个使用C#3的(测试!)示例:
using System.Net; // need this somewhere // need to declare an class so we can cast our state object back out class RequestState { public WebRequest Request { get; set; } } static void Main( string[] args ) { // stupid cast neccessary to create the request HttpWebRequest request = WebRequest.Create( "http://www.stackoverflow.com" ) as HttpWebRequest; request.BeginGetResponse( /* callback to be invoked when finished */ (asyncResult) => { // fetch the request object out of the AsyncState var state = (RequestState)asyncResult.AsyncState; var webResponse = state.Request.EndGetResponse( asyncResult ) as HttpWebResponse; // there we go; Debug.Assert( webResponse.StatusCode == HttpStatusCode.OK ); Console.WriteLine( "Got Response from server:" + webResponse.Server ); }, /* pass the request through to our callback */ new RequestState { Request = request } ); // blah Console.WriteLine( "Waiting for response. Press a key to quit" ); Console.ReadKey(); }
编辑:
在.NET的情况下,'完成回调'实际上是在ThreadPool线程中触发,而不是在主线程中,因此您仍然需要锁定任何共享资源,但它仍然可以节省管理线程的所有麻烦.