【问题标题】:Get object from Task and return from non-async method从 Task 获取对象并从非异步方法返回
【发布时间】:2013-05-31 13:36:53
【问题描述】:

我有一个较低级别的库,它是我设计为异步并返回任务的方法之一。

我知道在较低级别的库中使用异步方法不是一个好主意,但是没有办法绕过这个方法,因为处理非常繁重。

在我的低级库之间,我有一个主库,它公开了有问题的低级库方法。 “就像一个业务层”。

我的应用程序的入口点是一个 WEB Api,然后它调用中间层库,中间层调用最低层库。

我的相关问题是最好从我的中间库中异步链开始的最低级别库中解压缩结果,然后只向消费者公开一个静态方法,还是应该只为消费者提供一个异步方法并且只提供从最低到最高的异步方法?

从进入应用程序的第一个方法是:CutSheet.CutSheet cutSheet = AlumCloudPlans.Manager.GetCutSheet(elev);

我知道一定有更好的方法,因为在中级库上我必须创建一个全新的任务,返回值是一个任务,然后返回那个任务值。

你们会建议我在中级图书馆做什么?

---最低级别

namespace CutSheet
{
    public class Manager
    {
        public async static Task<CutSheet> GetCutSheet(IElevation elevation)
        {
            return new CutSheet(await new PartsProcessor.PartProcessor()
                                                 .ProcessParts(elevation));
        }
    }
}

---中级

namespace AlumCloudPlans
{
    public class Manager
    {    
        public static CutSheet.CutSheet GetCutSheet(IElevation elevation)
        {
            var t = Task.Factory.StartNew(async delegate
            {
                return await CutSheet.Manager.GetCutSheet(elevation);
            });

            t.Wait();
            return t.Result.Result;
        }

    }
}

---最高级别和进入应用程序

namespace StorefrontSystem.Controllers
{
    [Authorize]
    public class CutSheetController : AlumCloudWebApiBaseController
    {

        public async Task<HttpResponseMessage> Get(string a, string f, int id)
        {
            HttpResponseMessage r = Request.CreateResponse();

            IElevation elev = await ElevationManager.GetElevation(id);

            CutSheet.CutSheet cutSheet = AlumCloudPlans.Manager
                                                   .GetCutSheet(elev);

            var ms = new MemoryStream();
            bool isPDF = f.ToLower() == "pdf";

            if (isPDF)
            {
                using (var pdf = await cutSheet.GetCutSheetPDF(elev))
                {
                    pdf.Save(ms, false);
                }
            }
            else
            {    
                using (Bitmap canvas = await cutSheet.GetDrawing())
                {
                    canvas.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                }    
            }

            ms.Position = 0;
            r.Content = new StreamContent(ms);
            if (isPDF)
            {
                r.Content.Headers.ContentType 
                      = new Headers.MediaTypeHeaderValue("Application/pdf");
            }
            else
            {
                r.Content.Headers.ContentType 
                     = new Headers.MediaTypeHeaderValue("image/png");
            }
            return r;
        }
    }
}

【问题讨论】:

    标签: c# asp.net-web-api async-await class-library


    【解决方案1】:

    我知道在低级库中使用异步方法不是一个好主意

    谁告诉你的?只要您正在执行的操作自然是异步的,在任何级别都有async 方法是一个非常好的主意。但是,不是在较低级别假装使用Task.Run 异步的东西是一个好主意 - 这在 ASP.NET 中尤其如此。

    假设你的操作自然是异步的,你应该一直使用async

    中级:

    public class Manager
    {
        public static Task<CutSheet.CutSheet> GetCutSheetAsync(IElevation elevation)
        {
            return CutSheet.Manager.GetCutSheetAsync(elevation);
        }
    }
    

    最高级别:

    [Authorize]
    public class CutSheetController : AlumCloudWebApiBaseController
    {
        public async Task<HttpResponseMessage> Get(string a, string f, int id)
        {
            HttpResponseMessage r = Request.CreateResponse();
    
            IElevation elev = await ElevationManager.GetElevationAsync(id);
    
            CutSheet.CutSheet cutSheet = await AlumCloudPlans.Manager.GetCutSheetAsync(elev);
    
            ...
       }
    }
    

    【讨论】:

    • 当您说自然异步时,您的意思是什么?我还注意到您已经从中间级别删除了异步。那么,这是否告诉我,当我返回异步方法时,我的方法签名中不再需要异步?非常感谢!
    • 自然异步意味着它不仅仅是一个阻塞操作的包装器(包装器通常使用Task.RunTaskFactory.StartNew)。自然异步方法是一种不受 CPU 限制的方法。仅当您使用 await 关键字时,才需要关键字 async
    猜你喜欢
    • 2022-06-21
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 2021-04-18
    相关资源
    最近更新 更多