Multithreading design Best Practice

hlasů
3

Vezměme si tento problém: Mám program, který by měl načtení (řekněme) 100 záznamů z databáze a pak pro každý z nich by měl získat aktuální informace z webové služby. Existují dva způsoby, jak zavést paralelismu v tomto scénáři:

  1. Začnu každý požadavek na webovou službu na nové vlákno. Počet souběžných vláken je řízen nějakým vnějším parametru (nebo dynamicky nějak upravit).

  2. I vytvořit menší dávky (řekněme z každých 10 záznamů) a spusťte každou dávku na samostatné vlákno (takže při našem příkladě 10 vláken).

Což je lepší přístup, a proč si to myslíte?

Položena 13/08/2008 v 20:03
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
6

Varianta 3 je nejlepší:

Použít Async IO.

Pokud vaše zpracování požadavku je složitá a těžká, váš program stráví 99% je to čekal na požadavky HTTP čas.

To je přesně to, co asynchronní IO je určen pro - Let okna sítí zásobníku (nebo NET Framework nebo cokoliv) starat o vše na počkání, a stačí použít jediné vlákno odesláním a ‚vyzvednout‘ výsledky.

Bohužel to právo osina v zadku rámec .NET dělá. Je to jednodušší, pokud jste právě používáte raw socket nebo Win32 API. Zde je (testováno!) Příklad použití C # 3 tak jako tak:

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

UPRAVIT:

V případě .NET dokončovacích callback "ve skutečnosti vyhodí do ThreadPool nití, nikoli v hlavním vlákně, takže budete ještě potřebovat, aby zamknout žádné sdílené zdroje, ale to vám ještě uloží všechny problémy s řídícími nití.

Odpovězeno 14/08/2008 v 00:35
zdroj uživatelem

hlasů
3

Dvě věci, aby zvážila.

1. Jak dlouho bude trvat zpracování záznamu?

Pokud zpracování záznamů je velmi rychlý, režie předáním záznamy nití se může stát překážkou. V takovém případě by se chcete spojit záznamy, takže nemusíte jim ruce pryč tak často.

Pokud zpracování záznamů je poměrně dlouhotrvající, bude rozdíl zanedbatelný, takže jednodušší přístup (1 záznam na závitu) je pravděpodobně nejlepší.

2. Kolik nitě plánujete na zahájení?

Pokud nejste pomocí threadpool, myslím, že musíte buď ručně omezit počet závitů, nebo budete muset rozdělit data do velkých bloků. Spuštění nové vlákno pro každý záznam opustí váš systém výprask v případě, že počet záznamů zvětší.

Odpovězeno 13/08/2008 v 20:19
zdroj uživatelem

hlasů
0

Získat Paralelní Fx . Podívejte se na BlockingCollection. Použijte vlákno krmit dávek záznamů a 1 až n téma tahání záznamy z kolekce do provozu. Můžete ovládat rychlost, s jakou je kolekce nakrmena a počet závitů, které vyžadují k webovým službám. Ať je to konfigurovatelné přes ConfigSection, a učinit z něj generic krmením akčních delegátů sběru, a budete mít pěknou dávkovač můžete znovu použít na co hrdlo ráčí.

Odpovězeno 13/08/2008 v 20:40
zdroj uživatelem

hlasů
0

V počítači běží program pravděpodobně není překážkou, aby: Nezapomeňte, že protokol HTTP má hlavičku keep-alive, který umožňuje odesílat několik žádostí dostat na stejné zásuvky, což vám ušetří z chvění rukou TCP / IP. Bohužel nevím, jak používat, že v rozhraní .NET knihoven. (Mělo by být možné.)

Tam bude zřejmě také ke zpoždění v odpovědi na vaše požadavky. Dalo by se pokusit ujistit se, že jste vždy mít určitý počet nevyřízených požadavků na server.

Odpovězeno 13/08/2008 v 20:34
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more