为什么EPPlus在写入MemoryStream并在ASP.NET MVC应用程序中寻找零位置后抛出System.ObjectDisposedException: Cannot access a closed Stream.
?
public FileStreamResult ExportToExcel()
{
using (var memoryStream = new MemoryStream())
using (var excel = new ExcelPackage())
{
var worksheet = excel.Workbook.Worksheets.Add("Products");
worksheet.Cells["A1"].LoadFromCollection(Collection: myCollection, PrintHeaders: true);
excel.SaveAs(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin); // also tried memoryStream.Position = 0;
return new FileStreamResult(memoryStream, contentType)
{
FileDownloadName = "test.xlsx",
};
}
}
如果我将var memoryStream = ...
移出using
语句,它可以工作,但感觉这可能会泄漏大量内存,直到下一次垃圾收集,如果没有处理明确的。也许ExcelPackage也处理了MemoryStream?
[ObjectDisposedException: Cannot access a closed Stream.]
System.IO.__Error.StreamIsClosed() +57
System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count) +10653946
System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response) +80
System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context) +168
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52
System.Web.Mvc.Async.<>c__DisplayClass28.<BeginInvokeAction>b__19() +173
System.Web.Mvc.Async.<>c__DisplayClass1e.<BeginInvokeAction>b__1b(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +54
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629296
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
答案 0 :(得分:4)
我认为这是因为您的MemoryStream
是using
。
这会导致(在处理结束时)关闭和处理流。
让FileStreamResult
句柄关闭此内容,然后删除using
。