Używam Visual Studio 2012 RC z .Net 4.5 i ASP MVC 4 RC. Zawiesza się, gdy w ogóle korzystam z asynchronizacji. Metoda działania kontrolera używa asynchronizacji, ale sama nie jest metodą kontrolera asynchronicznego.Kontroler ASP.Net MVC 4 zawiesza się, gdy używany jest async.
Nie zgłoszono błędów ani nie zgłoszono wyjątków, ale przeglądarka wyświetla komunikat "Oczekiwanie na www.myweb.local" "na zawsze.
// Simplest possible async
public class Waiter
{
public async Task<int> GetValue()
{
await Task.Yield();
return await Task.Factory.StartNew(() => 42);
}
}
// simplest possible controller that uses the async
public class HomeController : Controller
public ActionResult Index()
{
var waiter = new Waiter();
var resultTask = waiter.GetValue();
int result = resultTask.Result;
// it never gets here
return View();
}
}
Zrobiłem rzeczy, które są odnotowane in this answer i nadal nie działa. tj. Web.config zawiera
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
A magiczne słowa await Task.Yield();
są w sposób asynchroniczny.
Wersja szkieletowa .Net ma numer 4.5.50501. Zaobserwowałem to zachowanie w usługach IIS Express i IIS 6.0.
Próbowałem zastosować "Aktualizacja z lipca 2012" do VS2012, ale to nie naprawiło.
This answer suggests że może być fakt, że zadanie zostało już zakończone, gdy czekam na niego, jednak gdyby tak było, to powinno działać i to nie:
public class Waiter
{
public async Task<int> GetValue()
{
await Task.Yield();
return await Task.Factory.StartNew(() =>
{
Thread.Sleep(1500);
return 42;
});
}
}
Kilka osób sugerowało, że ConfigureAwait(false)
jest potrzebna, ale ten kod nie działa albo:
public async Task<int> GetValue()
{
var task = new Task<int>(() => 42);
return await task.ConfigureAwait(false);
}
Poniższy działa z poglądem silnik brzytwa, ale nie z iskrą. Z pewnością powinien istnieć sposób na sprawdzenie, czy drugi scenariusz działa? Czy nie można używać zadań asynchronicznych wewnątrz kodu synchronicznego?
public class Waiter
{
public async Task<int> GetValue()
{
return await Task.Factory.StartNew(() => 42);
}
}
public class HomeController : Controller
{
public async Task<ActionResult> IndexAsync()
{
await Task.Yield();
var waiter = new Waiter();
int result = await waiter.GetValue();
return View();
}
}
wiem, że to nie jest zwolniony oprogramowanie, ale tras RC Microsoft są zazwyczaj dość stabilny, więc jestem zaskoczony, że to się nie powiedzie, a nie w bardzo nowoczesny sposób.
Przepraszam, jeśli coś pominąłem, ale dlaczego blok indeksu ma dostęp do właściwości wyników zamiast oznaczania jej asynchronicznie i czekania tam? Jeśli jest to celowe, może być konieczne użycie opcji ConfigureAwait (false), aby kontynuacja nie została ponownie uruchomiona w tym samym wątku. –
Testuję przeniesienie istniejącej witryny do .Net 4.5. Używa silnika widoku iskry.Chciałem uzyskać asynchroniczne działanie zanim zacząłem zajmować się kontrolerami async i czy iskra może obsłużyć zadanie, czy nie (moje pierwsze wrażenie było nie). Ale niezależnie od tego, czy mógłbym to zrobić, czy nie, scenariusz ten powinien zadziałać. –
Anthony
Dlaczego czerpiecie z AsyncController? To nie jest konieczne. Zobacz mój przykład asynchroniczny http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4 – RickAndMSFT