簡體   English   中英

從Task獲取對象並從非異步方法返回

[英]Get object from Task and return from non-async method

我有一個較低級的庫,該庫是我設計為異步並返回Task的方法之一。

我知道在較低級別的庫中使用異步方法不是一個好主意,但是由於處理的繁瑣,因此無法解決這一問題。

在我的低級庫之間,我有一個主庫,它公開了所涉及的低級庫方法。 “就像一個業務層”。

我的應用程序的入口點是WEB Api,然后調用中級庫,而中級則調用最低級庫。

我的相關問題是,最好從最低層庫中解壓縮結果,在該最低層庫中,異步鏈從我的中間庫開始,然后向消費者公開一個靜態方法,或者我應該只為消費者提供一個異步方法而僅向消費者提供?從最低到最高的異步方法?

從應用程序的入口開始,有問題的第一個方法是: CutSheet.CutSheet cutSheet = AlumCloudPlans.Manager.GetCutSheet(elev);

我知道必須有一個更好的方法,因為在中級庫上,我必須創建一個全新的任務,並且返回值是value,這是一個Task,然后返回該Task的值。

您會建議我在中級庫中做什么?

-最低水平

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

我知道在較低級別的庫中使用異步方法不是一個好主意

誰告訴你的? 只要您正在執行的操作自然是異步的,那么在任何級別上都具有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);

        ...
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM