0

非同期で Task を返すように設計したメソッドの 1 つである下位レベルのライブラリがあります。

下位レベルのライブラリに非同期メソッドを含めるのは良い考えではないことはわかっていますが、処理が非常に激しいため、これを回避する方法はありません。

低レベル ライブラリの間に、問題の低レベル ライブラリ メソッドを公開するメイン ライブラリがあります。「まるでビジネス層」。

私のアプリのエントリ ポイントは 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;
        }
    }
}
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 に答える