2012-07-13 13 views
7

Wymiana wątków (nie wątek wątku) z asynchronicznymi delegatami (wywołania zwrotne).Asynchroniczne delegatów kontra wątki

Mój scenariusz: zaimportuj wątek/del.beginInvoke() na klienta.

Według mnie,

Powody

  1. konieczności powiadamiania poprzez oddzwaniania/Call delegata ponownie w zwrotnego
  2. Unikać Overhead gwintu (delegaci używać puli wątków wątek)
  3. Przekazywanie argumentów (Unikaj Casting to object) i wymaga zwracania wartości z metody.

Popraw mnie, jeśli powyższe powody są złe.

  1. Czy istnieją inne powody?
  2. W jakim scenariuszu potrzebuję zrobić coś z Asynchronicznymi Delegatami, których wątki nie mogą znaleźć się w wątkach ?
    3. Wydajność?

Przykład

public delegate void SendCallbackType(); 

    SendCallbackType senderdel= new SendCallbackType(SendData); 

    public void StartSend() // This method Could be Called more than 700 times (Thread per Client) 
    { 
     senderdel.BeginInvoke(SendCallback,null); 
        // (or) 
     Thread t = new Thread(new ThreadStart(ThreadSend)); 
     t.IsBackground = true; 
     t.Start(); 
    } 

    //Async Delegate 
    void SendData() 
    { 
     string data = QueData.DeQueue(); 
     RaiseOnData(data); // Raise to event. 
    } 
    void SendCallback(IAsyncResult ar) 
    { 
     senderdel.BeginInvoke(SendCallback, null); 
    } 

//Thread 
    void ThreadSend() 
    { 
     while (true) 
     { 
     string data = QueData.DeQueue(); 
     RaiseOnData(data); // Raise to event. 
     } 
    } 

Z powyższego która opcja najlepsze. Wydajność ?

Odpowiedz

10

Twoje rozumowanie jest prawidłowe. Asynchroniczni delegaci używają wątków z puli wątków, więc powinny być szybsze w porównaniu do ręcznego tworzenia wątków. Bądź jednak ostrożny z tym w aplikacjach ASP.NET. Ponieważ zajmiemy się wątkami roboczymi, które są zwykle używane przez ASP.NET do obsługi zgłoszeń, a twoja aplikacja może bardzo szybko przestać obsługiwać.

Delegatury asynchroniczne są odpowiednie do zadań wymagających dużej mocy obliczeniowej. W przypadku zadań intensywnych I/O (takich jak odczytywanie strumieni, wywołań baz danych i wywołań usług WWW) należy używać metod BeginXXX, EndXXX oferowanych bezpośrednio przez odpowiednie klasy (Stream, SqlConnection, WebClient, ...). W ten sposób nie używasz żadnych wątków podczas długiej operacji we/wy. Używasz I/O Completion Ports, co jest najlepszą rzeczą pod względem zadań związanych z I/O. Będą to rzędy wielkości bardziej wydajne i taniej niż nici i pule wątków.

Więc Podsumowując:

  • I/O intensywnych zadań użyć I/O Zakończenie Porty. Jeśli zadanie intensywne I/O jest opakowane w źle napisaną bibliotekę, która nie oferuje tej możliwości, skorzystaj z licencji TPL, która została wprowadzona w .NET 4.0.
  • W przypadku zadań intensywnych dla procesora użyj TPL, który został wprowadzony w .NET 4.0.

Jeśli nie masz .NET 4.0 użyj puli wątków, chyba że piszesz aplikację ASP.NET, w takim przypadku możesz użyć ręcznego tworzenia wątków.

Ogólnie rzecz biorąc, dobrą praktyką jest rozpoczęcie korzystania z TPL i ukierunkowanie swoich metod jako zadań, abyś był gotowy na platformę .NET 4.5, która wprowadza asynchroniczne/oczekiwane słowa kluczowe.

+0

@ Darin: Dzięki za odpowiedź.Tutaj przypadkiem jest Windows Application, myślę, że czysto CPU intensywne zadania, co o wydajności podczas tarła 1000 wątków vs 1000 del.begininvoke() zadzwoń –

+0

@ MSK, zdecydowanie iść z TPL w tym przypadku i jeśli używasz starszej wersji. NET używa puli wątków (ThreadPool, BackgroundWorker, Async delegates, ... => one wszystkie będą w końcu w ThreadPool). Nie spawaj wątków ręcznie w tej sytuacji. –

+0

@ Darin: I nie potrzebuję Ognia i zapomnij. Tutaj potrzebuję dedykowanego wątku do usunięcia (bez względu na ThreadPool) i jednocześnie jest to proces długotrwały. –