1

外部ライブラリ サービスで最初に作成されたタスクを返す Web API コントローラーがあります。サービスからコントローラーまでのすべてのチェーンで Task を返しますが、問題は、そのコントローラーへの HTTP 呼び出しを行うときに、初めて API を開始したときです (初回は常に少し時間がかかります)。期待される結果は完全に、2回目のリクエストを行うと、..部分的な結果が返されます。

デバッグすると、常に期待される正しい結果が返されます。明らかに、今待っているものがあります..

コードは次のとおりです。

        public async Task<HttpResponseMessage> DownloadBinary(string content)
        {
            byte[] recordToDown =  await ExternalLibraryConverter.GetAsync(content);

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(recordToDown)
            };
            result.Content.Headers.ContentDisposition =
                new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                {
                    FileName = "Test file"
                };

            // added so Angular can see the Content-Disposition header
            result.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");

            result.Content.Headers.ContentType =
                new MediaTypeHeaderValue("application/pdf");

            return result;
        }

そしてサービス:

        public static async Task<byte[]> GetAsync(string content)
        {

            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision)
                .ConfigureAwait(false);
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true,
            }).ConfigureAwait(false);

            using (var page = await browser.NewPageAsync().ConfigureAwait(false))
            {
                await page.SetCacheEnabledAsync(false).ConfigureAwait(false);

                await page.SetContentAsync(content).ConfigureAwait(false);

                await page.AddStyleTagAsync("https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,600,700").ConfigureAwait(false);

                // few more styles add

                var result = await page.GetContentAsync().ConfigureAwait(false);

                PdfOptions pdfOptions = new PdfOptions()
                {
                    PrintBackground = true,
                    MarginOptions = new PuppeteerSharp.Media.MarginOptions {
                        Right = "15mm", Left = "15mm", Top = "20mm", Bottom = "20mm" },
                };
                byte[] streamResult = await page.PdfDataAsync(pdfOptions)
                    .ConfigureAwait(false);

                browser.Dispose();

                return streamResult;
            }
        }

ご覧のとおり、外部ライブラリを使用したサービスには多くの待機があります。await が使用されているすべての場所で ConfigureAwait(false) を使用しようとしましたが、どちらも役に立ちませんでした。

4

1 に答える 1

3

コントローラー レベルで .ConfigureAwait を実行するべきではないと思います。詳細については、この記事を参照してください: https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html

ASP.NET チームは SynchronizationContext の使用を中止したため、コントローラーで使用しても意味がありません。

記事に記載されているように、UI がそれ自体をサービスにプラグインして使用できるかどうかわからないため、サービス レベルで引き続き使用する必要がありますが、Web API ではドロップできます。

于 2019-09-04T12:47:11.647 に答える