2012-07-05 4 views
7
ben vermek istiyoruz çalıştırmak için 10-20 saniye sürebilir bir eylem varsa burada http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

ASP.NET MVC 4 Async Kontrolör Geri arama

açıklandığı gibi sadece MVC 4 yeni zaman uyumsuz Kontrolör özelliklerini kullanıyorum

ilerlemeyi bildiren bir tür durum çubuğu. Async özelliklerinde buna yardımcı olacak bir şey var mı?

DÜZENLEME: Ben denemek ve bunu nasıl bir bıçak alıp daha iyi yollar

public async Task<ActionResult> GizmosAsync() 
{ 
    return View("Gizmos", await GetGizmosAsync()); 
} 

private void GetGizmosAsync() 
{ 
    for(int i=0; i<10; i++) 
    { 
     lock(_locker) 
     { 
      _statusMessage = String.Format("{0} of 10", i); 
     } 
     DoSomethingLongRunning(); 
    } 
} 

public ActionResult Status() 
{ 
    return Json(new { Status = _statusMessage }); 
} 

static readonly object _locker = new object(); 

static string _statusMessage = ""; 

.... 

<script> 

setTimeout(displayStatus, 1000); 

function displayStatus() { 
    $.post("/controller/status", function(data) { 
    alert(data.Status); 
    }); 
} 

</script> 

cevap

15

Async denetleyicileri varsa sırayla IIS içinde ThreadPool'da gelen konuları kurtararak sadece bir mekanizmadır göreceksiniz Ağır yük sırasında gelen istekleri ele alabilmek için, ancak müşteri ile iletişim, her zamanki istek-yanıtı olarak kalır.

Durum çubukları ve sıralama genellikle ajax isteği tamamlanıncaya kadar ekranda bir şey gösteren javascript olur. MVC4'ün bu kısımda yardımcı olacağını düşünmüyorum.

ajax çağrıları sırasında "işleniyor ..." <div> görüntülemek için https://stackoverflow.com/a/68503/1373170 gibi bir şey yapabilirsiniz.

DÜZENLEME: Gerçek ilerleme müşteri ve etkileşim (gerçek ilerleme gibi) gerekiyorsa, SignalR http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx Ve bu ilgili yazıyı kontrol etmelisiniz: Async Controllers (MVC), long running process with "stops"

+0

Evet, zaten böyle bir şey yapmak ama aynı mesajı 10 saniye boyunca ise insanların sistem asılı düşünüyorum. – Craig

+0

Eh, uygun gelmediğini biliyorum, ancak bazen ilerlemenin "yanılsaması" kullanıcıların ihtiyaç duyduğu şeydir. Örneğin, görevinizin ortalama 15 sn sürdüğünü biliyorsanız, js kullanarak o süre boyunca bir ilerleme çubuğunu otomatikleştirin. Kullanıcıyı kandırmak gibi gözükebileceğini biliyorum, ancak gerçekten bir yerde, bir veritabanı gibi kısmi ilerlemeyi saklamanın ve kesin ilerleme için istemci tarafı yoklama işleminizin gerçekten çok fazla uğraştığı bazı durumlar var. –

+0

SignalR'ı düşünmemiştim, muhtemelen işe yarayacaktı. – Craig

5

Bu makale ne anlatmak görünüyor sen istiyorum:

ASP.NET MVC 3: Async jQuery progress indicator for long running tasks

Denetleyici:

public class HomeController : Controller 
{ 
    private static IDictionary<Guid, int> tasks = new Dictionary<Guid, int>(); 

    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult Start() 
    { 
     var taskId = Guid.NewGuid(); 
     tasks.Add(taskId, 0); 

     Task.Factory.StartNew(() => 
     { 
      for (var i = 0; i <= 100; i++) 
      { 
       tasks[taskId] = i; // update task progress 
       Thread.Sleep(50); // simulate long running operation 
      } 
      tasks.Remove(taskId); 
     }); 

     return Json(taskId); 
    } 

    public ActionResult Progress(Guid id) 
    { 
     return Json(tasks.Keys.Contains(id) ? tasks[id] : 100); 
    } 
} 

Görünüm:

<script type="text/javascript"> 

function updateMonitor(taskId, status) { 
    $("#" + taskId).html("Task [" + taskId + "]: " + status); 
} 

$(function() { 
    $("#start").click(function (e) { 
    e.preventDefault(); 
    $.post("Home/Start", {}, function (taskId) { 

    // Init monitors 
    $("#monitors").append($("<p id='" + taskId + "'/>")); 
    updateMonitor(taskId, "Started"); 

    // Periodically update monitors 
    var intervalId = setInterval(function() { 
     $.post("Home/Progress", { id: taskId }, function (progress) { 
     if (progress >= 100) { 
      updateMonitor(taskId, "Completed"); 
     clearInterval(intervalId); 
     } else { 
      updateMonitor(taskId, progress + "%"); 
     } 
     }); 
     }, 100); 
    }); 
    }); 
}); 
</script> 
<div id="monitors"></div> 
+1

Yük dengeli çoklu AppDomain ortamı kullanıyorsanız iyi değil. – divinci