.net之多线程设计最佳实践

yyy_WW 阅读:44 2024-08-22 11:11:09 评论:0

考虑这个问题:我有一个程序应该从数据库中获取(比如说)100 条记录,然后对于每条记录,它都应该从 Web 服务中获取更新的信息。在这种情况下,有两种方法可以引入并行性:

  1. 我在一个新线程上启动对 Web 服务的每个请求。同时线程的数量由一些外部参数控制(或以某种方式动态调整)。

  2. 我创建较小的批处理(假设每个 10 条记录)并在单独的线程上启动每个批处理(以我们的示例为例,10 个线程)。

哪种方法更好,您为什么这么认为?

请您参考如下方法:

选项 3 是最好的:

使用异步 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 线程中触发的,而不是在您的主线程中,因此您仍然需要锁定任何共享资源,但它仍然为您省去了管理的所有麻烦线程。


标签:多线程
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号