【问题标题】:Http.IMiddleware Do not create tasks without passing a TaskSchedulerHttp.IMiddleware 不通过TaskScheduler就不要创建任务
【发布时间】:2020-04-17 02:39:23
【问题描述】:

(.Net 3.1,Visual Studio 2019)

在DevExpress代码示例中:https://github.com/DevExpress-Examples/blazor-server-dxdatagrid-export/blob/19.2.2%2B/CS/DxDataGridExportingWithReports/Helpers/ExportMiddleware.cs,下面的http中间件代码得到了

的警告

不通过TaskScheduler就不要创建任务...

重写代码以启动新任务的正确方法是什么?

public class ExportMiddleware : IMiddleware
{
    ......

    public Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
       ......

        _ = await new TaskFactory().StartNew(() => // warning: Do not create tasks without passing a TaskScheduler
        {
            report.CreateDocument();
            using (MemoryStream fs = new MemoryStream())
            {
                if (format == pdf)
                    report.ExportToPdf(fs);
                else if (format == xlsx)
                    report.ExportToXlsx(fs);
                else if (format == docx)
                    report.ExportToDocx(fs);
                context.Response.Clear();
                context.Response.Headers.Append("Content-Type", "application/" + format);
                context.Response.Headers.Append("Content-Transfer-Encoding", "binary");
                context.Response.Headers.Append("Content-Disposition", "attachment; filename=ExportedDocument." + format);
                context.Response.Body.WriteAsync(fs.ToArray(), 0, fs.ToArray().Length);
                return context.Response.CompleteAsync();
            }
        });

【问题讨论】:

  • 你为什么要使用任务来完成这项工作?您认为创建自己的任务工厂在这里给您带来什么?

标签: c# asp.net asp.net-core devexpress task-parallel-library


【解决方案1】:

从技术上讲,要回答实际问题,代码应该使用Task.Run 而不是StartNew

_ = Task.Run(() =>

但是,这是一个非常糟糕的主意。这不仅是在做fire-and-forget,它还会在未来的某个随机时间使用context.Response。它会开始写入响应流,然后在写入完成之前完成流。它完全坏了。

相信一个更合适的解决方案是完全删除工厂/启动/运行并在必要时使用await

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
  ......
  report.CreateDocument();
  using (MemoryStream fs = new MemoryStream())
  {
    if (format == pdf)
      report.ExportToPdf(fs);
    else if (format == xlsx)
      report.ExportToXlsx(fs);
    else if (format == docx)
      report.ExportToDocx(fs);
    context.Response.Clear();
    context.Response.Headers.Append("Content-Type", "application/" + format);
    context.Response.Headers.Append("Content-Transfer-Encoding", "binary");
    context.Response.Headers.Append("Content-Disposition", "attachment; filename=ExportedDocument." + format);
    await context.Response.Body.WriteAsync(fs.ToArray(), 0, fs.ToArray().Length);
    await context.Response.CompleteAsync();
  }
}

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多