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

标签 .net multithreading

考虑这个问题:我有一个程序应该从数据库中获取(比如说)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 线程中触发的,而不是在您的主线程中,因此您仍然需要锁定任何共享资源,但它仍然为您省去了管理的所有麻烦线程。

关于.net - 多线程设计最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10229/

相关文章:

.net - FixedDocument打印问题(由TeamViewer解决??)

c# - 与 Oracle 数据库连接失败

java - Java 守护线程是否与生成进程共享堆或 Perm Gen?

multithreading - 如何避免线程?

java - 在本例中,为什么优先级较低的线程没有在优先级较高的线程之后执行?

c# - 契约.net : Get the request that was sent to the mock service

c# - 为什么我的 .NET 组件上的索引器并不总是可以从 VBScript 访问?

.net - ASP.net MVC - 使用 EditorFor 两次相同的模型类型

java - 无法在 AsyncTask 中启动新 Activity

android - 尽管 UncaughtExceptionHandler 间歇性 Android 应用程序崩溃,但没有错误日志