• asp.net mvc 特性 使用异步Controllers


    使用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 seconds

    public 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);

  • 相关阅读:
    HDU 3280 Equal Sum Partitions(二分查找)
    提高效率—编程中的技巧
    开发心得
    使用OpenCV读、操作、写图像并与bash合作对某个文件夹下全部图像进行相似处理
    观察者模式
    ORA-00932: inconsistent datatypes: expected
    Struts1应用、实现简单计算器、使用DispatchAction、显示友好的报错信息、使用动态Form简化开发
    Apple Swift编程语言新手教程
    I NEED A OFFER! (hdu 1203 01背包)
    端午遥想
  • 原文地址:https://www.cnblogs.com/wusong/p/1976559.html
Copyright © 2020-2023  润新知