asp.net mvc 特性 使用异步Controllers
2011-03-07 23:49
375 查看
使用asp.net异步执行请求的原因和好处,可以搜之,不赘叙。
看一个同步抓取网页图片的方法:
Public ContentResult GetPhotoByTag(string tag){
// Make a request to Flickr
string url = string.Format(FlickrSearchApi, HttpUtility.UrlEncode(tag));
using (var response = WebRequest.Create(url).GetResponse())
{
// Parse the response as XML
Var xmlDoc = XDocument.Load(XmlReader.Create(response.GetResponseStream()));
// Use LINQ to convert each <photo /> node to a URL string
var photoUrls = from photoNode in xmlDoc.Descendants("photo")
select string.Format(
"http://farm{0}.static.flickr.com/{1}/{2}_{3}.jpg",
photoNode.Attribute("farm").Value,
photoNode.Attribute("server").Value,
photoNode.Attribute("id").Value,
photoNode.Attribute("secret").Value);
// Return an <img> tag referencing the first photo
return Content(string.Format("<img src='{0}'/>", photoUrls.First()));
}
}
改写成异步。
实现异步Controller 3个关键点:1,继承自AsyncController
2,方法名称格式:ActionNameAsync, ActionNameCompleted。
3,设置信号量
public class ImageController : AsyncController
{
public void GetPhotoByTagAsync(string tag)
{
AsyncManager.OutstandingOperations.Increment();
// Begin an asynchronous request to Flickr
string url = string.Format(FlickrSearchApi, HttpUtility.UrlEncode(tag));
WebRequest request = WebRequest.Create(url);
request.BeginGetResponse(asyncResult =>
{
// This lambda method will be executed when we've got a response from Flickr
using (WebResponse response = request.EndGetResponse(asyncResult))
{
// Parse response as XML, then convert to each <photo> node to a URL
var xml = XDocument.Load(XmlReader.Create(response.GetResponseStream()));
var photoUrls = from photoNode in xml.Descendants("photo")
select string.Format(
"http://farm{0}.static.flickr.com/{1}/{2}_{3}.jpg",
photoNode.Attribute("farm").Value,
photoNode.Attribute("server").Value,
photoNode.Attribute("id").Value,
photoNode.Attribute("secret").Value);
AsyncManager.Parameters["photoUrls"] = photoUrls;
// Now allow the Completed method to run
AsyncManager.OutstandingOperations.Decrement();
}
}, null);
}
public ContentResult GetPhotoByTagCompleted(IEnumerable<string> photoUrls)
{
return Content(string.Format("<img src='{0}'/>", photoUrls.First()));
}
}
使用异步三部曲:1,方法名称:XXXXXAsync,XXXXXCompleted;2,一步方法中通过信号量控制同步:逻辑开始前递增信号量AsyncManager.OutstandingOperations.Increment();逻辑后递减信号量 AsyncManager.OutstandingOperations.Decrement();3,传参数和执行结果: AsyncManager.Parameters["photoUrls"] = photoUrls;
如何给completed传参数:
public void GetPhotoByTagAsync(string tag, string someOtherParam){
AsyncManager.Parameters["someOtherParam"] = someOtherParam;
// ... all else as before ...
}
public ContentResult GetPhotoByTagCompleted(IEnumerable<string> photoUrls,
string someOtherParam)
{
// ...
}
通过AsyncManager.Parameters集合传键值对参数,Completed方法会试图通过参数名称去匹配参数值。
如何指定超时:
[AsyncTimeout(10000)] // 10000 milliseconds equals 10 secondspublic void GetPhotoByTagAsync(string tag) { ... }
如何终止异步操作。
这里提供的方法比较粗暴,只能用AsyncManager.Finish()把所有未完成异步调用终止。该方法导致Completed提早调用,AsyncManager.Parameters里面的值会设置为默认值(0,null..etc)。使用Sync() 强制回调方法运行在绑定了原始 HTTPContext的asp.net工作线程上:
在control中,假如异步方法带有回调,那么该回调将不可预见在什么线程上执行。自然不能肯定的去访问HTTPContext。解决办法是使用AsyncManager.Sync。示例:BeginAsyncOperation (asyncResult => {
var result = End (asyncResult);
// Can't always access System.Web.HttpContext.Current from here...
Action doSomethingWithHttpContext = () => {
// ... but can always access it from this delegate
};
if (asyncResult.CompletedSynchronously) // Already on an ASP.NET thread
doSomethingWithHttpContext();
else // Must switch to an ASP.NET thread
AsyncManager.Sync(doSomethingWithHttpContext);
AsyncManager.OutstandingOperations.Decrement();
}, null);
相关文章推荐
- ASP.NET MVC 3 Razor 中的 @helper 特性的使用例子
- ASP.NET MVC中使用ASP.NET AJAX异步访问WebService
- 返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作
- 在ASP.NET MVC中使用Knockout实践06,自定义验证、异步验证
- ASP.NET MVC异步上传图片和富文本编辑器的使用详解
- ztree 使用asp.net mvc异步动态获取数据
- 使用ASP.NET MVC Futures 中的异步Action
- 在 ASP.NET MVC 中使用异步控制器
- 填充区域 (Populating an Area) | 使用区域 | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼
- 译文:使用MVC5的Entity Framework 6入门(九)——为ASP.NET MVC应用程序使用异步及存储过程
- 使用ASP.NET MVC Futures 中的异步Action
- ASP.NET MVC什么时候使用异步Action
- 【转载】返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作
- ASP.NET MVC中使用ASP.NET AJAX异步访问WebService
- 深入ASP.NET MVC Model验证-使用.NET验证特性类指定Mode验证规则
- ASP.NET MVC什么时候使用异步Action
- 使用ASP.NET MVC Futures 中的异步Action
- 使用ASP.NET MVC Futures 中的异步Action 【转】
- 使用ASP.NET MVC Futures 中的异步Action 推荐