0

I've got a lower level library that one of the methods I've designed to be async and to return a Task.

I know it is not a good idea to have async methods in lower level libraries, but there is no way around this one, because of how heave the processing is.

In between my lower level library I've got a main library that exposes the lower level library method in question. "Just like a business layer".

The entry point of my app is a WEB Api it then calls the mid level library and the the mid level calls the lowest level library.

My relevant question is would it be better to unpack the result from the lowest level library where the async chain begin inside my mid library and then expose just a static method to the consumer, or should I just offer the consumer a async method and just offer async methods from the lowest to the highest?

From the entry into the app the first method in question is: CutSheet.CutSheet cutSheet = AlumCloudPlans.Manager.GetCutSheet(elev);

I know there must be a better way because on the mid level library I've got to create an entire new task and the return is value, which is a Task, and the return that Task value.

What would ya'll recommend that I do in the mid level library?

---Lowest level

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

---Mid level

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;
        }

    }
}

---Highest level and entry to app

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;
        }
    }
}
4

1 回答 1

4

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

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

假设你的操作自然是异步的,你应该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);

        ...
   }
}
于 2013-06-05T01:39:46.773 回答