public class HomeController AsyncController
{
public Task<ActionResult> Article(string name)
{
return Task.Factory.StartNew(() =>
{
string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"articles{0}.html", name));
using (StreamReader reader = new StreamReader(path))
{
AsyncManager.Parameters["content"] = reader.ReadToEnd();
}
}).ContinueWith<ActionResult>(task =>
{
string content = (string)AsyncManager.Parameters["content"];
return Content(content);
});
}
}
上面定义的异步Action方法Article的返回类型为Task<ActionResult>,我们将异步文件内容的读取体现在返回的Task对象中。对文件内容呈现的回调操作则通过调用该Task对象的ContinueWith<ActionResult>方法进行注册,该操作会在异步操作完成之后被自动调用。
如上面的代码片断所示,我们依然利用AsyncManager的Parameters属性实现参数在异步操作和回调操作之间的传递。其实我们也可以使用Task对象的Result属性来实现相同的功能,Article方法的定义也改写成如下的形式。
public class HomeController AsyncController
{
public Task<ActionResult> Article(string name)
{
return Task.Factory.StartNew(() =>
{
string path = ControllerContext.HttpContext.Server.MapPath(string.Format(@"articles{0}.html", name));
using (StreamReader reader = new StreamReader(path))
{
return reader.ReadToEnd();
}
}).ContinueWith<ActionResult>(task =>
{
return Content((string)task.Result);
});
}
}
三、AsyncManager
在上面演示的异步Action的定义中,我们通过AsyncManager实现了两个基本的功能,即在异步操作和回调操作之间传递参数和向ASP.NET MVC发送异步操作开始和结束的通知。由于AsyncManager在异步Action场景中具有重要的作用,我们有必要对其进行单独介绍,下面是AsyncManager的定义。
public class AsyncManager
{
public AsyncManager();
public AsyncManager(SynchronizationContext syncContext);
public EventHandler Finished;
public virtual void Finish();
public virtual void Sync(Action action);
public OperationCounter OutstandingOperations { get; }
public IDictionary<string, object> Parameters { get; }
public int Timeout { get; set; }
}
public sealed class OperationCounter
{
public event EventHandler Completed;
public int Increment();
public int Increment(int value);
public int Decrement();
public int Decrement(int value);
public int Count { get; }
}
如上面的代码片断所示,AsyncManager具有两个构造函数重载,非默认构造函数接受一个表示同步上下文的SynchronizationContext对象作为参数。如果指定的同步上下文对象为Null,并且当前的同步上下文(通过SynchronizationContext的静态属性Current表示)存在,则使用该上下文;否则创建一个新的同步上下文。该同步上下文用于Sync方法的执行,也就是说在该方法指定的Action委托将会在该同步上下文中以同步的方式执行。








