Multithreading Desain Praktek Terbaik

Mempertimbangkan masalah ini: saya memiliki program yang harus mengambil (let's mengatakan) 100 catatan dari database, dan kemudian untuk setiap satu ini harus mendapatkan informasi terbaru dari web service. Ada dua cara untuk memperkenalkan paralelisme dalam skenario ini:

  1. Aku memulai setiap permintaan untuk layanan web di Thread baru. Jumlah simultan benang dikendalikan oleh beberapa parameter eksternal (atau disesuaikan secara dinamis entah bagaimana).

  2. Saya membuat batch yang lebih kecil (let's mengatakan dari 10 catatan masing-masing) dan peluncuran masing-masing batch pada thread terpisah (jadi kami mengambil contoh, 10 benang).

Yang merupakan pendekatan yang lebih baik, dan mengapa anda berpikir begitu?

Mengomentari pertanyaan (3)
Larutan

Opsi 3 adalah yang terbaik:

Menggunakan Async-IO.

Kecuali permintaan anda diproses lebih kompleks dan berat, program anda akan menghabiskan 99% it's waktu menunggu permintaan HTTP.

Ini adalah persis apa yang Async-IO dirancang untuk Membiarkan windows networking stack (atau .net framework atau apapun) khawatir tentang semua menunggu, dan hanya menggunakan satu benang untuk pengiriman dan 'pick up' hasil.

Sayangnya .NET framework membuatnya kanan sakit di pantat. It's lebih mudah jika anda're hanya menggunakan bahan baku soket atau Win32 api. Berikut ini's a (tested!) misalnya dengan menggunakan C#3 pokoknya:

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();
}

EDIT:

Dalam kasus .BERSIH, 'penyelesaian callback' benar-benar dipecat dalam ThreadPool benang, bukan di thread utama, sehingga anda masih akan perlu untuk mengunci semua berbagi sumber daya, tetapi itu masih menyimpan anda semua kesulitan mengelola thread.

Komentar (1)

Dua hal yang perlu dipertimbangkan.

1. Berapa lama waktu yang dibutuhkan untuk proses rekaman?

Jika pemrosesan data sangat cepat, overhead menyerahkan catatan untuk benang yang dapat menjadi hambatan. Dalam hal ini, anda akan ingin untuk bundel catatan sehingga anda don't harus menyerahkan mereka begitu sering.

Jika catatan pengolahan cukup lama berjalan, perbedaan akan diabaikan, sehingga pendekatan yang lebih sederhana (1 record per benang) mungkin adalah yang terbaik.

2. Berapa banyak benang yang anda berencana untuk memulai?

Jika anda tidak't menggunakan threadpool, saya pikir anda perlu untuk secara manual membatasi jumlah thread, atau anda perlu untuk memecah data ke dalam potongan besar. Memulai thread baru untuk setiap record akan meninggalkan sistem anda meronta-ronta jika jumlah record mendapatkan besar.

Komentar (1)

Komputer yang menjalankan program ini mungkin tidak hambatan, sehingga: Ingat bahwa protokol HTTP memiliki keep-alive header, yang memungkinkan anda mengirim beberapa MENDAPATKAN permintaan pada soket yang sama, yang menyelamatkan anda dari TCP/IP berjabat tangan. Sayangnya saya don't tahu bagaimana untuk menggunakannya dalam .net perpustakaan. (Harus mungkin.)

Ada juga kemungkinan akan ada keterlambatan dalam menjawab permintaan anda. Anda bisa mencoba membuat yakin bahwa anda allways telah diberikan jumlah yang luar biasa permintaan ke server.

Komentar (0)

Mendapatkan Paralel Fx. Melihat BlockingCollection. Gunakan benang untuk memberi makan itu kumpulan dari catatan-catatan, dan 1 untuk n benang catatan menarik dari koleksi untuk layanan. Anda dapat mengontrol tingkat di mana collection makan, dan jumlah benang yang menelepon ke layanan web. Membuat dikonfigurasi melalui ConfigSection, dan membuatnya generik dengan makan collection Tindakan delegasi, dan anda'll have a nice little batcher anda dapat kembali ke hati anda's konten.

Komentar (0)