1

我正在制作一个控制器,它应该返回从另一台服务器下载的文件的压缩列表(放置在同一个数据中心)

我为这一刻做了什么:

/// <summary>
/// Enables processing of the result of an action method by a custom type that inherits from the <see cref="T:System.Web.Mvc.ActionResult"/> class.
/// </summary>
/// <param name="context">The context in which the result is executed. The context information includes the controller, HTTP content, request context, and route data.</param>
public override void ExecuteResult(ControllerContext context)
{
    context.HttpContext.Response.ContentType = "application/zip";
    context.HttpContext.Response.CacheControl = "private";
    context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    context.HttpContext.Response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}\"", this.ResultFileName));

    var buffer = new byte[BufferSize];

    using (var zippedUploadStream = new ZipOutputStream(context.HttpContext.Response.OutputStream))
    {
        zippedUploadStream.SetLevel(0);

        foreach (var url in this.Urls)
        {
            var request = WebRequest.Create(url);
            var response = request.GetResponse();
            var downloadStream = response.GetResponseStream();

            if (downloadStream != null)
            {
                var zipEntry = new ZipEntry(Path.GetFileName(response.ResponseUri.ToString()));
                zippedUploadStream.PutNextEntry(zipEntry);

                int read;
                while ((read = downloadStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    zippedUploadStream.Write(buffer, 0, read);
                    context.HttpContext.Response.Flush();
                }
            }

            if (!context.HttpContext.Response.IsClientConnected)
            {
                break;
            }
        }

        zippedUploadStream.Finish();
    }

    context.HttpContext.Response.Flush();
    context.HttpContext.Response.End();
}

让我害怕的是,所有操作都是同步的。

如果我离开这个实现,对性能的影响会有多大?

是否可以从另一个线程访问 context.HttpContext.Response 对象?

可以使用异步调用优化此代码吗?

4

1 回答 1

0

您真的不想在 Web 请求线程中执行这样的任务。这些类型的长时间运行、系统资源密集型任务最好使用某种排队或消息总线系统来执行。我推荐类似NServiceBus的东西来完成这项任务。您可以使用 NServiceBus 将消息排入队列,而不是从单个 Web 请求线程中同步创建多个 Web 请求。然后,NServiceBus 将获取这些消息中的每一个(可能是异步的,取决于配置)并分别处理它们。这样做的好处是您可以获得 MSMQ 的可靠性和持久性优势,NServiceBus 将其用作其消息队列。

于 2012-11-10T04:52:04.173 回答