Cannot access a disposed object when Upload file in Background Service

Hoài Nam Nguyễn 41 Reputation points
2024-04-16T12:52:22.7866667+00:00

This is the error I am facing:

Error occurred executing workItem.
      System.ObjectDisposedException: Cannot access a disposed object.
      Object name: 'System.String'.
         at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
         at Microsoft.AspNetCore.Http.ReferenceReadStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
         at System.IO.Stream.<CopyToAsync>g__Core|27_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
         at Microsoft.AspNetCore.Http.FormFile.CopyToAsync(Stream target, CancellationToken cancellationToken)
         at UploadFile.Api.Controllers.VideoController.<>c__DisplayClass4_0.<<UploadFile>b__1>d.MoveNext() in C:\Users\User\source\repos\UploadFileBackground\UploadFile.Api\Controllers\VideoController.cs:line 52
      --- End of stack trace from previous location ---
         at UploadFile.Api.ServiceUpload.QueuedHostedService.BackgroundProcessing(CancellationToken stoppingToken) in C:\Users\User\source\repos\UploadFileBackground\UploadFile.Api\ServiceUpload\QueuedHostedService.cs:line 32

I did follow this guide: hosted-services

This is my file upload api:

const long MaxFileSize = 1L * 1024L * 1024L * 1024L; // 1GB

[HttpPost]
[DisableFormValueModelBinding]
[RequestSizeLimit(MaxFileSize)]
[RequestFormLimits(MultipartBodyLengthLimit = MaxFileSize)]
public async Task<IActionResult> UploadFile(List<IFormFile> files)
{            
    var title = Request.Form.FirstOrDefault(x => x.Key == "title").Value.ToString();
    if (string.IsNullOrEmpty(title))
    {
        return BadRequest("title is empty");
    }
    if (!files.Any())
    {
        return BadRequest("There is no file");
    }
    Func<CancellationToken, ValueTask> uploadWorkItem = async (token) =>
    {
        string UploadFolder = Path.Combine(Directory.GetCurrentDirectory(), "VideoUpload");
        foreach (var file in files)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            string UploadPath = Path.Combine(UploadFolder, file.FileName);
            using (var stream = System.IO.File.Create(UploadPath))
            {
                await file.CopyToAsync(stream);
                _logger.LogInformation("Finshed copy file.");
            }
        }
    };    
    await _taskQueue.QueueBackgroundWorkItemAsync(uploadWorkItem);            
    return NoContent();
}

When I use postman call api, the above error appears.

and the error occurs as soon as await workItem(stoppingToken) is running

private async Task BackgroundProcessing(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        var workItem = await TaskQueue.DequeueAsync(stoppingToken);
        try
        {
            await workItem(stoppingToken);// error is throw at here
        }
        catch (Exception ex)
        {
            _logger.LogError(ex,"Error occurred executing {WorkItem}.", nameof(workItem));
        }
    }
}

Can anyone help me fix this error. Thank for all

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,175 questions
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 56,286 Reputation points
    2024-04-16T17:57:00.22+00:00

    you are passing the variable "files" by closure to the background thread, but when the controller completes the action, it disposes the request variables like IFormFiles.

    the action would need to delay until the background thread completes before exiting, but this would defeat the purpose. In general background threads can not access any request/response objects. You need to clone (if possible) before passing.

    if the uploads are not large, you can copy the stream steams to new streams. be sure to read to end before passing to background thread.


0 additional answers

Sort by: Most helpful