MVC2 What's new part 2.

Achronous Controller - asynchroniczne kontrolery
Asynchroniczne wywołania mogą poprawić wydajność aplikacji, jednak zawsze powodują dużo większe skomplikowanie kodu.
W artykule na MSDN wymienione jest kilka punktów kiedy warto używać asynchronicznych wywołań jak np. długo trwające operacje wejścia-wyjścia, inne długo trwające operacje, czy nastawienie na wielowątkowość.

Klasyczny kontroler (z klasycznym przykładem) wywołania z jakiegoś serwisu:
public class HomeController : Controller
{
    public ActionResult Index()
    {
        var client = new News.NewsServieceClient();
        var news = client.GetNewsList();
        return View(news);
    }
}

Aby stworzyć wersje asynchroniczną:
  • dziedziczymy po AsyncController zamiast zwykłego Controller
  • funkcję Index (czy też każdą inną) rozbijamy na dwie:
    IndexAsync
    IndexCompleted
  • wymieniamy wnętrzności funkcji aby stworzyć wersje async
  • używamy AsyncManager
    Gdy wywołujemy operacje inkrementujemy ilość operacji w AsyncManager za pomocą:
    AsyncManager.OutstandingOperations.Increment();
    Jeśli były by jeszcze jakieś operacje oprócz przykładowego pobierania wiadomości np. pobieranie wiadomości sportowych, również zinkrementowalibyśmy OutstandingOperations a AsyncManager wiedziałby że są to dwie operacje.
    Kiedy zostanie obsłużona funkcja Completed danej operacji wywołamy
    AsyncManager.OutstandingOperations.Decrement();
    Tym sposobem kiedy zakończą się wszystkie operacje AsyncManager będzie wiedział że należy wywołać IndexCompleted.
A oto wersja asynchroniczna, z dodatkowymi wyjaśnieniami.
  public class HomeController : AsyncController
    {
        //brak zwracanej wartości - tylko przygotowanie operacji
        public void IndexAsync()
        {
            var client = new NewsServiceClient();
            
            //musimy obsłużyć Completed z serwisu który wołamy 
            client.GetNewsItemsCompleted += (sender, args) =>
            {
                // rezultat wykonania przekazujemy do AsyncManager
                // parametry zostaną przekazane do fukcji "IndexCompleted"  
                AsyncManager.Parameters["news"] = args.Result;
                //Informujemy AsyncManager o obecnej ilości operacji 
                AsyncManager.OutstandingOperations.Decrement();
            };

            //Informujemy AsyncManager o obecnej ilości operacji 
            AsyncManager.OutstandingOperations.Increment();
            //serwis który wołamy oczywiście musi obsługiwać wywołania asynchroniczne
            client.GetNewsItemsAsync();
        }
        
        /// funkcja Completed wykonuje jakąś akcję (generuje widok)
        /// na podstawie parametru przekazanego z operacji async
        public ActionResult IndexCompleted(object news)
        {
            return View(news);
        }
    }

Komentarze

  1. Cieszę się, że znów publikujesz ;) Ciekawa sprawa z tym kontrolerem ;)

    OdpowiedzUsuń

Prześlij komentarz

Popularne posty