webservice此时无法启动异步操作

问题描述 投票:0回答:1

我有一个网络服务可以使用 PuppeteerSharp 将 html 转换为 pdf,但是这一行

await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);

返回此错误

此时无法启动异步操作。 异步操作只能在异步处理程序或模块中或在页面生命周期中的某些事件期间启动。 如果在执行页面时发生此异常,请确保页面标记为 <%@ Page Async="true" %>。 此异常还可能指示尝试调用“async void”方法,这在 ASP.NET 请求处理中通常不受支持。 相反,异步方法应该返回一个任务,调用者应该等待它。

我的代码:

    [WebMethod]
    public string HtmlToPdf(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF)
    {
        try
        {
            GestionTraza.Utilidades.escribirLog("WSTOPDF", string.Join(" ", " -- Arranca el proceso de transformación de HTML a PDF"), LogTrazas.DBG, LogCapas.CN, 34);                

            bool orientacion = (orientacionPagina == "V" ? false : true);

            var fichero = GenerarPdf(htmlString, imagenCabecera, altoCabecera, orientacionPagina, anchoPagina, leftMargin, rightMargin, topMargin, bottomMargin, textoPie);
            fichero.Wait();

            return fichero.Result;

        } catch (Exception e)
        {
            GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "HtmlToPdf", "HtmlToPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
            throw e;
        }
        
    }

    private async Task<string> GenerarPdf(string htmlString, string imagenCabecera, int altoCabecera, string orientacionPagina, int anchoPagina, string leftMargin, string rightMargin, string topMargin, string bottomMargin, string textoPie) {

        string outputFile = "";

        try
        {
            bool orientacion = (orientacionPagina == "V" ? false : true);                

            Console.WriteLine("Downloading chromium");
            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);

            Console.WriteLine("Navigating google");
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions
            {
                Headless = true
            });
            var page = await browser.NewPageAsync();
            await page.GoToAsync(htmlString);
            await page.PdfAsync(outputFile, new PdfOptions
            {
                HeaderTemplate = imagenCabecera,
                Height = altoCabecera,
                Landscape = orientacion,
                //OmitBackground = false,
                //PageRanges =,
                //PreferCSSPageSize = ,
                //PrintBackground =,
                //Scale =,
                Width = anchoPagina,
                Format = PaperFormat.A4,
                DisplayHeaderFooter = true,
                MarginOptions = new MarginOptions
                {
                    Top = topMargin,
                    Right = rightMargin,
                    Bottom = bottomMargin,
                    Left = leftMargin
                },
                //FooterTemplate = "<div id=\"footer-template\" style=\"font-size:10px !important; color:#808080; padding-left:10px\">Footer Text</div>"
                FooterTemplate = textoPie
            });

            return outputFile;
        }
        catch (Exception e)
        {
            GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "GenerarPdf", "GenerarPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
            throw e;
        }            
    }
}
}
c# asynchronous async-await webmethod
1个回答
1
投票

您可能需要考虑升级您的网络框架。微软在 2006 年开始建议人们远离 ASMX,并在 2009 年正式宣布 ASMX 为“遗留技术”。现在是 2023 年; ASMX 已经死了(或者“维护中”,如果你愿意的话)将近 15 年.

但是,假设您不能升级到现代框架,有一种方法可以让它工作。

首先,必须以.NET Framework 4.5(或更高版本)为目标,

httpRuntime@targetFramework
设置为
4.5
(或更高版本)
。如果您仍在使用 .NET Framework 4.0(即 Windows XP),那么完全停止:您根本不能使用
async
await
(在 ASP.NET 项目中)。

一旦您的目标是 4.5 或更高版本(并将

targetFramework
设置为
4.5
或更高版本),您就可以使用异步
WebRequest
方法。不幸的是,ASMX 是一项遗留技术,它不理解或支持
async
/
await
。您可以在自己的方法中使用
async
/
await
,但不能在任何标有
WebRequest
的方法中使用。相反,您需要使用您的 TAP 方法并将它们作为 APM 方法提供给 ASMX。像这样的东西:

[WebMethod]
public IAsyncResult BeginHtmlToPdf(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF, AsyncCallback callback, object state)
{
  var tcs = new TaskCompletionSource<string>(state);
  var task = HtmlToPdfAsync(htmlString, baseURL, ...);
  task.ContinueWith(t =>
  {
    if (t.IsFaulted)
      tcs.TrySetException(t.Exception.InnerExceptions);
    else if (t.IsCanceled)
      tcs.TrySetCanceled();
    else
      tcs.TrySetResult(t.Result);

    if (callback != null)
      callback(tcs.Task);
  });

  return tcs.Task;
}

[WebMethod]
public string EndHtmlToPdf(IAsyncResult result)
{
  return ((Task<string>)result).GetAwaiter().GetResult();
}

private async Task<string> HtmlToPdfAsync(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF)
{
  try
  {
    GestionTraza.Utilidades.escribirLog("WSTOPDF", string.Join(" ", " -- Arranca el proceso de transformación de HTML a PDF"), LogTrazas.DBG, LogCapas.CN, 34);                

    bool orientacion = (orientacionPagina == "V" ? false : true);

    return await GenerarPdf(htmlString, imagenCabecera, altoCabecera, orientacionPagina, anchoPagina, leftMargin, rightMargin, topMargin, bottomMargin, textoPie);
  }
  catch (Exception e)
  {
    GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "HtmlToPdf", "HtmlToPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
    throw e;
  }
}

我不完全确定它是否适用于你的情况,因为你有大量的论据,但值得一试。

© www.soinside.com 2019 - 2024. All rights reserved.