【发布时间】:2012-02-02 10:30:41
【问题描述】:
在 ASP.NET MVC 上,我尝试使用旧的异步编程模型(实际上是当前的,新的仍然是 CTP)编写一个异步控制器动作。
在这里,我尝试并行运行 4 个操作,效果很好。完整代码如下:
public class SampleController : AsyncController {
public void IndexAsync() {
AsyncManager.OutstandingOperations.Increment(4);
var task1 = Task<string>.Factory.StartNew(() => {
return GetReponse1();
});
var task2 = Task<string>.Factory.StartNew(() => {
return GetResponse2();
});
var task3 = Task<string>.Factory.StartNew(() => {
return GetResponse3();
});
var task4 = Task<string>.Factory.StartNew(() => {
return GetResponse4();
});
task1.ContinueWith(t => {
AsyncManager.Parameters["headers1"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
task2.ContinueWith(t => {
AsyncManager.Parameters["headers2"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
task3.ContinueWith(t => {
AsyncManager.Parameters["headers3"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
task4.ContinueWith(t => {
AsyncManager.Parameters["headers4"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
task3.ContinueWith(t => {
AsyncManager.OutstandingOperations.Decrement();
}, TaskContinuationOptions.OnlyOnFaulted);
}
public ActionResult IndexCompleted(string headers1, string headers2, string headers3, string headers4) {
ViewBag.Headers = string.Join("<br/><br/>", headers1, headers2, headers3, headers4);
return View();
}
public ActionResult Index2() {
ViewBag.Headers = string.Join("<br/><br/>", GetReponse1(), GetResponse2(), GetResponse3(), GetResponse4());
return View();
}
}
下面这些是异步操作正在运行的方法:
string GetReponse1() {
var req = (HttpWebRequest)WebRequest.Create("http://www.twitter.com");
req.Method = "HEAD";
var resp = (HttpWebResponse)req.GetResponse();
return FormatHeaders(resp.Headers);
}
string GetResponse2() {
var req2 = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");
req2.Method = "HEAD";
var resp2 = (HttpWebResponse)req2.GetResponse();
return FormatHeaders(resp2.Headers);
}
string GetResponse3() {
var req = (HttpWebRequest)WebRequest.Create("http://google.com");
req.Method = "HEAD";
var resp = (HttpWebResponse)req.GetResponse();
return FormatHeaders(resp.Headers);
}
string GetResponse4() {
var req = (HttpWebRequest)WebRequest.Create("http://github.com");
req.Method = "HEAD";
var resp = (HttpWebResponse)req.GetResponse();
return FormatHeaders(resp.Headers);
}
private static string FormatHeaders(WebHeaderCollection headers) {
var headerStrings = from header in headers.Keys.Cast<string>()
select string.Format("{0}: {1}", header, headers[header]);
return string.Join("<br />", headerStrings.ToArray());
}
我这里还有Index2 方法,它是同步的并且做同样的事情。
我比较了两个操作的执行时间,有很大的不同(大约 2 秒)
但我认为我在这里遗漏了很多东西(异常处理、超时等)。我只在 task3 上实现异常处理,但我认为这不是正确的做法。
处理此类操作的异常最健康的方法是什么?
【问题讨论】:
标签: asp.net-mvc multithreading asp.net-mvc-3 asynchronous exception-handling