SORU
5 Ocak 2012, PERŞEMBE


ASP.NET MVC zaman uyumsuz işlemleri Havuzu bir iplik kullanın .NET 4

Bu sorudan sonra zaman uyumsuz kullanırken beni rahat yapar ASP.NET MVC işlemleri. Bu konuda iki blog yazdım:

ASP.NET MVC üzerinde zaman uyumsuz işlemler hakkında aklımda çok fazla yanlış anlama var.

Hep bu cümleyi duyuyorum:Uygulama, işlem zaman uyumsuz olarak çalıştırmak için iyi bir ölçek

Ve cümleler bu tür bir çok şey de duydum:eğer trafik büyük bir ses, sorgu zaman uyumsuz sahne değil, daha iyi olabilir - bir isteğe hizmet için ek bir iş parçacığı başka gelen istekleri uzak kaynaklarını alır tüketen 2.

Bu iki cümle tutarsız olduğunu düşünüyorum.

ASP.NET üzerinde nasıl çalıştığı hakkında fazla bilgi sahibi değilim ama o havuzu iş parçacığı için sınırlı bir boyutu olduğunu biliyorum. Yani ikinci cümle bu sorunla ilgili olmalı.

Ve eğer ASP.NET MVC zaman uyumsuz işlemleri Havuzu bir iş parçacığı kullanıyorsa bilmek istiyorum .NET 4?

Örneğin, biz bir AsyncController uygulamak, uygulamayı nasıl yapılar? Eğer büyük trafik olsun, AsyncController uygulamak için iyi bir fikir mi?

Bu siyah perde çekip gözlerimin önünde alıp bana açıklayabilecek birileri ASP.NET üzerinde asynchrony hakkında anlaşmanın 3 (NET 4) MVC var mı?

Düzenleme:

Belge yüzlerce kez neredeyse aşağıda bu okudum ve ana anlaşma anlıyorum ama yine de çok tutarsız yorum var çünkü karışıklık var.

Using an Asynchronous Controller in ASP.NET MVC

Düzenleme:

Hadi gibi (AsyncController gerçi bir uygulama değil) aşağıda denetleyicisi eylem var varsayalım:

public ViewResult Index() { 

    Task.Factory.StartNew(() => { 
        //Do an advanced looging here which takes a while
    });

    return View();
}

Burada gördüğünüz gibi, ben bir operasyon ateşle ve unut. Sonra, ben hemen tamamlanmasını beklemeden dönmek.

Bu durumda, bu havuzu bir iş parçacığı kullanmak zorunda mı? Tamamlandıktan sonra, eğer bu konuya ne olur? GC gelir ve tamamlandıktan sonra temizlemek mi?

Düzenleme:

@Darin cevabı için, burada veritabanı için yaptığı görüşmeler, zaman uyumsuz kod bir örnektir:

public class FooController : AsyncController {

    //EF 4.2 DbContext instance
    MyContext _context = new MyContext();

    public void IndexAsync() { 

        AsyncManager.OutstandingOperations.Increment(3);

        Task<IEnumerable<Foo>>.Factory.StartNew(() => { 

           return 
                _context.Foos;
        }).ContinueWith(t => {

            AsyncManager.Parameters["foos"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        Task<IEnumerable<Bars>>.Factory.StartNew(() => { 

           return 
                _context.Bars;
        }).ContinueWith(t => {

            AsyncManager.Parameters["bars"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        Task<IEnumerable<FooBar>>.Factory.StartNew(() => { 

           return 
                _context.FooBars;
        }).ContinueWith(t => {

            AsyncManager.Parameters["foobars"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });
    }

    public ViewResult IndexCompleted(
        IEnumerable<Foo> foos, 
        IEnumerable<Bar> bars,
        IEnumerable<FooBar> foobars) {

        //Do the regular stuff and return

    }
}

CEVAP
5 Ocak 2012, PERŞEMBE


Burada okuma daha iyi ASP.NET asenkron denetleyicileri temelde neyi temsil () zaman uyumsuz işleme anlamanı tavsiye ederim excellent article.

İlk standart eşzamanlı bir eylem ele alalım:

public ActionResult Index()
{
    // some processing
    return View();
}

Bir istek bu eylem için bir iş parçacığı iş parçacığı havuzu çekilir ve bu eylemin vücut bu konu üzerinde yürütülür. Eğer öyleyse bu eylem içinde işleme yavaş ise tüm işlem için bu konuyu kapatıyorsunuz, bu konuyu başka istekleri işlemek için kullanılabilir. İsteği sonunda yürütme iş parçacığı için iş parçacığı havuzu döndürülür.

Şimdi zaman uyumsuz desen örnek alın:

public void IndexAsync()
{
    // perform some processing
}

public ActionResult IndexCompleted(object result)
{
    return View();
}

Bir istek Dizin eylem için gönderildiğinde, bir iş parçacığı iş parçacığı havuzu çizilir ve IndexAsync yöntem gövdesi yürütülür. Bu yöntem vücut çalıştırma tamamlandıktan sonra, bu iş parçacığı için iş parçacığı havuzu döndürülür. Daha sonra, kullanarak standart AsyncManager.OutstandingOperations, bir kez sinyal tamamlama zaman uyumsuz işlem, başka bir iş parçacığı çizilir gelen iş parçacığı havuzu ve vücut IndexCompleted eylem çalıştırılır ve sonucu işlenen istemci.

Bu yüzden bu deseni görebiliyoruz ne tek istemci bir HTTP isteği iki farklı iş parçacığı tarafından yürütülecek.

Şimdi ilginç bölümü IndexAsync yöntemin içinde olur. Eğer bir engelleme işlemi içinde, tamamen israf bütün amacı, zaman uyumsuz denetleyicileri çünkü engelleme worker (unutmayın ki, vücut bu eylemi yürütülen bir iplik bile kalmasını parçacığı havuzu).

Ne zaman diye sorabilirsiniz asenkron denetleyicileri gerçek yararlanabilir miyiz?

IMHO ben varken en kazanç/yoğun operasyonları (uzaktan hizmetler için veritabanı ve ağ aramaları gibi) O edebiliriz. Eğer CPU yoğun bir operasyon varsa, zaman uyumsuz eylemler pek bir fayda getirmez.

Neden G/Ç yoğun faaliyetlerden elde yararlanabilir miyiz? I/O Completion Ports kullanabiliriz. IOCP tüm operasyon yürütülürken sunucuda herhangi bir iş parçacığı veya kaynaklarını tüketir yok, çünkü son derece güçlü.

Nasıl çalışır?

Uzak bir web sayfası WebClient.DownloadStringAsync yöntemi kullanarak içeriğini indirmek istiyoruz varsayalım. İşletim sistemi içinde bir IOCP kayıt ve hemen geri dönecek olan bu yöntemi çağırın. Tüm istek işlenirken, hiçbir iş parçacığı sunucu üzerinde tüketiliyor. Her şey uzak sunucuda olur. Bu çok zaman alabilir ama işçi konuları tehlikeye atıyorsun değil, umurunda değil. Bir yanıt IOCP sinyal alındığında, bir iş parçacığı iş parçacığı havuzu çekilir ve geri bu iş parçacığında yürütülür. Ama gördüğünüz gibi, tüm süreç boyunca, herhangi bir iş parçacığı, tekel değiliz.

Aynı duruyor FıleStream gibi yöntemlerle gerçek.BeginRead, SqlCommand., ... BeginExecute

Ne birden çok veritabanı aramaları parallelizing? 4 sıra veritabanı aramaları engelleme işlemi zaman uyumlu denetleyici bir eylem olduğunu varsayalım. Kolay, her veritabanı arama 200ms, kontrol sürerse eylem kabaca 800ms yürütmek için alacağını hesaplamak için.

Eğer bu çağrıları sırayla çalıştırmak için ihtiyacınız varsa, parallelizing onların performansını artırmak istiyorsunuz?

O kadar kolay değil ki en büyük soru. Belki Evet, belki hayır. Tamamen bu veritabanı aramaları nasıl bağlıdır. Zaman uyumsuz denetleyicileri kullanın ve daha önce tartışıldığı gibi O Tamamlama Bağlantı Noktaları, g/eğer işçi iş parçacığı tekeline olmayacak gibi bu denetleyici eylem ve diğer eylemleri performansını da artırmak olacaktır.

Diğer taraftan eğer uygulamak onları kötü (bir engelleme veritabanı arama yapılan bir iş parçacığı iş parçacığı havuzu), tost daha düşük toplam zaman yürütme bu eylem için yaklaşık 200ms ama olurdu tüketilen 4 işçi iş parçacığı yani belki senin de bozulmuş performansı diğer istekleri bir hale açlıktan dolayı eksik iş parçacığı havuzu için süreç onları.

O kadar zor ki ve eğer uygulama üzerinde kapsamlı testler gerçekleştirmek için hazır hissetmiyorsun bile, şansını yarardan çok zarar olacak gibi asenkron denetleyicileri uygulamak. Eğer bunu yapmak için bir nedeniniz varsa, sadece onları uygulamak: örneğin standart senkron denetleyici eylemleri uygulamanız için bir darboğaz (geniş yük testleri ve elbette ölçümleri gerçekleştirdikten sonra) olduğunu belirledik.

Ah, başka bir örneği ele alalım

public ViewResult Index() { 

    Task.Factory.StartNew(() => { 
        //Do an advanced looging here which takes a while
    });

    return View();
}

Bir istek Dizin eylem için alınan bir iş parçacığı iş parçacığı havuzu vücudu çalıştırmak için çizilir, ama vücudu sadece yeni görev kullanarak bir TRAFİK zamanlar. Eylem son bulur ve bu iş parçacığı için iş parçacığı havuzu döndürülür. Bunun dışında, TRAFİK iş parçacığı havuzu iş parçacığı işlemleri gerçekleştirmek için kullanır. Eğer öyleyse özgün iş parçacığı iş parçacığı havuzu dönmüş olsaydı bile, bu havuzdan başka bir iş parçacığı görev vücudu çalıştırmak için çizilmiş. Değerli havuzundan 2 iş parçacığı tehlikeye attın.

Hadi şimdi bir düşünün

public ViewResult Index() { 

    new Thread(() => { 
        //Do an advanced looging here which takes a while
    }).Start();

    return View();
}

Bu durumda el ile bir iş parçacığı arttı. Bu durumda Dizin eylem gövdesi yürütme biraz daha uzun yeni bir konu yumurtlama varolan bir havuzdan bir çizim daha pahalı olduğu için () sürebilir. Ama gelişmiş günlük operasyon yürütme havuzunun bir parçası olan bir iş parçacığı üzerinde yapılır. Başka bir istekleri hizmet için serbest kalır havuzu iş parçacığı tehlikeye değiliz yani.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jonathan Morrison

    Jonathan Mor

    24 Mart 2010
  • Kiddyzuzaa

    Kiddyzuzaa

    25 ŞUBAT 2014
  • The Slow Mo Guys

    The Slow Mo

    15 AĞUSTOS 2010