2010-12-01 12 views
15

ile uygulanan uzun süren bir görev için bir İlerleme çubuğu uygulama ASP.NET MVC 2'de documentation on AsyncControllers okuduktan sonra, bu senaryoda bir ajax ilerleme çubuğu uygulamak için en iyi yolun ne olduğunu merak ediyorum. Öğreticinin bunu hiçbir şekilde içermediği biraz garip görünüyor.Bir ASP.NET MVC 2 AsyncController

Bir AJAX ilerleme çubuğunu uygulamak, geçerli görev durumunu döndüren ek eylem yöntemi gerektirir. Ancak, çalışan iş parçacıkları ile bu eylem yöntemi arasındaki görev durumu hakkında bilgi alışverişi yapmanın en iyi yolundan emin değilim.

Şimdiye kadarki en iyi düşüncem, Oturum Sözlüğüne yapılan düzenli ilerlemeyle ilgili bilgileri benzersiz bir kimlik ile birlikte koymak ve bu kimliği istemciyle paylaşarak durumun anlaşılmasını sağlayabilmekti. Ama belki de fark etmediğim çok daha kolay bir yol var.

Bunu yapmanın en iyi yolu nedir?

sayesinde

Adrian

+0

Bu, normal bir istek için neden ilerleme çubuğu almadığınızı sormak gibidir. Bu şekilde düşündüğünüzde kendinize cevap vermelisiniz. – nick

+2

@nick: Gerçekten değil. Normal istekler uzun süredir çalışmıyor. Kimse en fazla birkaç saniye süren bir şey için ilerleme çubuğuna ihtiyaç duymaz. Ancak, bir uyumsuz denetleyici kullanıyorsanız, isteğin uzun sürmesini beklersiniz. Ve o zaman bir ilerleme çubuğuna ihtiyacınız var. Bunu anlatan tek kişi ben miyim? –

+0

Bir Async denetleyicisiyle, bir görevin başka bir yere aktarılacağı anlamına gelir - bu nedenle Async'i yaparsınız ve kodun geri kalanının sürekliliğini sürdürmesine izin verebilir - bunlardan herhangi birinin uzun süren bir görev olması gerekmez. Sadece performansı artırabileceğiniz anlamına gelir. Bir web isteği ile - müşteri tarafından herhangi bir fayda fark edilecektir.Sen tek misin? Bu bir şey mi söylüyor? Ne bekliyorsun? Sunucu, birden fazla yanıt göndermeye devam edecek, böylece bir ilerleme çubuğu elde edeceksiniz - bu, performans avantajlarınızı olumsuz etkileyecek ve gerçekten aptalca davranışlar ekleyecektir. – nick

cevap

16

Çok ilginç soru! Aslında AsyncController için bir görev değil gibi görünüyor. Async denetleyicileri, sunucu tarafında uzun süren tek-HTTP sorgulama işlemleri için tasarlanmıştır. Zaman uyumsuz eylemi kullandığınızda, bu işlem yalnızca uzun süren işlem (ler) sırasında ASP.Net çalışanı iş parçacığı yayınlamanıza ve işlem gerçekleştirilirken başka isteklerde bulunmasına izin vermenize yardımcı olabilir. Ama müşteri açısından bakıldığında farketmez, bu async kontrolörüdür ya da değildir. İstemci için bu sadece tek bir HTTP isteğidir.

Uygulamanızda uzun süredir devam eden sorgulama hizmetlerini kullanarak bunu yeniden tasarlamanız gerekir.

public class LongOperationsController : Controller 
{ 
    public ActionResult StartOperation(OperationData data) 
    { 
     Guid operationId = Guid.NewGuid(); // unique identifier for your operation 
     OperationsService.DoStartOperation(operationId, data); // service starts to perform operation using separate thread 
     return new JsonResult(operationId); // operation id should be sent to client to allow progress monitoring 
    } 

    public ActionResult GetOperationStatus(Guid operationId) 
    { 
     var status = OperationsService.GetStatus(operationId); // this method returns some object, that describes status of operation (e.g. progress, current task etc.) 
     return new JsonResult(status); // returning it to client 
    } 

    public ActionResult GetOperationResult(Guid operationId) 
    { 
     var result = OperationsService.GetOperationResult(operationId); // this should throw exception if operation is not yet completed 
     return new JsonResult(result); 
    } 

    public ActionResult ClearOperation(Guid operationId) 
    { 
     OperationsService.ClearOperationResult(operationId); // we should delete operation result if it was handled by client 
     return true; 
    } 
} 

Ve burada istemci tarafı kodu vardır, bu denetleyici ile etkileşim olabilir: İşte böyle iş akışını hizmet edebilir kumandanın örneği olduğunu

var operationId; 
function startOperation(data) { 
    $.post('/LongOperations/StartOperation', data, function(response) { 
     operationId = response; // store operationId 
     startOperationMonitoring(); // start 
    }, 'json'); 
} 

function startOperationMonitoring() { 
    // todo : periodically call updateOperationStatus() to check status at server-side 
} 

function updateOperationStatus() { 
    // todo : get result of GetOperationStatus action from controller 
    // todo : if status is 'running', update progress bar with value from server, if 'completed' - stop operation monitoring and call finishOperation() 
} 

function finishOperation() { 
    // todo : get result of GetOperationResult action from controller and update UI 
    // todo : call ClearOperation action from controller to free resources 
} 

Bu çok temel bir kavramdır bulundurulması gereken bazı Burada kaçırılan öğeler, ama umarım ana fikri alırsınız. Ayrıca örneğin, bu sistemin bileşenlerini tasarımı nasıl size kalmış: OperationsService, veya olmasın için

  • kullanımı tekil;
  • nerede ve ne kadar süreyle işlem sonucu saklanmalıdır (DB? Cache? Oturum?); istemci vb

İyi şans operasyonu (kullanıcı kapalı tarayıcı) izlemek için durduğunda

  • gerçekten elle yapmak kaynak ve ne serbest bırakmak için gereklidir!

  • +0

    Merhaba mace, Detaylı cevabınız için teşekkürler. Tam da benim de geldiğim ve OP'imin üçüncü paragrafında anlattığım yaklaşım. Bu iyi çalışıyor, ancak hemen hemen her async denetleyicisinin (yani bir ilerleme çubuğu) parçası olması gereken çok sıkıcı bir uygulama gibi görünüyor. ASP.NET MVC'nin bundan daha iyi olduğunu düşündüğüm (veya en azından umduğum) ve async denetleyicileri için bir çeşit ilerleme göstergesi sağladım. –

    +1

    Async denetleyicilerinin ne için tasarlandığını tam olarak anlayamadığınızı merak ediyorum. Onun async istekleri işleme ile ilgili değil, onun sunucu üzerinde uzun operasyonları çalıştırmak hakkında. Ne yazık ki, HTTP eşzamanlı bir protokoldür ve başlangıçtan beri bu amaçlar için tasarlanmamıştır. –

    +0

    Ayrıca, bence, açık bir talepte bulunmayı ve paralel istekleri kullanarak ilerlemeyle ilgili periyodik olarak sunucuyu kontrol etmenin en iyi fikri bu değil. –