【发布时间】:2014-05-15 04:23:44
【问题描述】:
我正在使用 MVC 4 和 .NET 4.5。我希望利用新的 TAP(异步等待)构建一个异步控制器。我从Controller 而不是AsyncContoller 继承了这个控制器,因为我使用的是基于任务的异步性,而不是基于事件的异步性。
我有两种操作方法 - 一种用于同步执行操作,另一种用于异步执行相同的操作。我的视图中的表单中还有两个提交按钮,每个操作方法一个。
以下是这两种方法的代码:
同步:
[HttpPost]
public ActionResult IndexSync(FormCollection formValues)
{
int Min = Int32.Parse(formValues["txtMin"]);
int Count = Int32.Parse(formValues["txtCount"]);
string Primes;
DateTime started = DateTime.Now;
using (BackendServiceReference.ServiceClient service = new ServiceClient())
{
Primes = service.GetPrimesServiceMethod(Min, Count);
}
DateTime ended = DateTime.Now;
TimeSpan serviceTime = ended - started;
ViewBag.ServiceTime = serviceTime;
ViewBag.Primes = Primes;
return View("Index");
}
异步:
[HttpPost]
public async Task<ActionResult> IndexAsync(FormCollection formValues)
{
int Min = Int32.Parse(formValues["txtMin"]);
int Count = Int32.Parse(formValues["txtCount"]);
string Primes;
Task<string> PrimesTask;
DateTime started = DateTime.Now;
using (BackendServiceReference.ServiceClient service = new ServiceClient())
{
PrimesTask = service.GetPrimesServiceMethodAsync(Min, Count);
}
DateTime ended = DateTime.Now;
TimeSpan serviceTime = ended - started;
ViewBag.ServiceTime = serviceTime;
Primes = await PrimesTask;
ViewBag.Primes = Primes;
return View("Index");
}
在异步方法中,我希望DateTime ended = DateTime.Now在调用服务方法后立即执行,而耗时的服务方法在后台异步执行。
但是,这不会发生,并且在调用服务方法时执行“等待”,而不是等待Primes = await PrimesTask 发生的位置。
我有什么遗漏的吗?
我们将不胜感激。
【问题讨论】:
-
您的异步调用是在您调用“Primes = await PrimesTask;”时进行的- 不在使用 AFAIK
-
@MichaelSkarum 使用断点调试,我发现执行“等待”在
PrimesTask = service.GetPrimesServiceMethodAsync(Min, Count)。为什么会这样?不应该在Primes = await PrimesTask等待吗? -
GetPrimesServiceMethodAsync 里面有什么?你可能在那里阻塞。请注意,await 不会启动新线程(很多人都认为)。
-
@usr 我在 WCF 服务中定义了一个简单的同步方法
GetPrimesServiceMethod(返回string)。GetPrimesServiceMethodAsync(返回Task<string>)是WCF在客户端消费生成的代理方法。 -
那应该没问题。在等待期间暂停调试器。查看调用堆栈(包括外部代码)。这将告诉我们那里正在运行什么并提示为什么。
标签: c# .net asp.net-mvc asp.net-mvc-4 asynchronous