如何使ASP.NET Core Web API操作异步执行?

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

我在ASP.NET Core Web API中的控制器中有一个上传和处理文件的操作。文件很小时没关系,但如果文件很大怎么办?我希望这个动作是异步执行的,所以我将方法定义为async,它的返回值只是Task是等待的,并在await Task.Run(() => ...)块中插入连续操作,使动作也是async并用await关键字调用此方法,但实际上,调用此方法后,此操作不会返回。我试图上传大文件,不得不等到文件完全上传和处理。那么,我该怎么做才能使这个动作真的异步执行呢?

c# asynchronous asp.net-core-webapi
2个回答
1
投票

您的Web Api项目的调用方不知道C#细节,Task是什么或await的意思。它可能是C#或JS,甚至是PHP或在浏览器栏中键入您的URL的人。

您的Web Api默认情况下(并且应该!)等待整个处理完成,然后发出一个成功的信号。这通常通过状态代码作为返回值来完成。

现在调用API的客户端不必等待它。但这是客户端编程。你无法在API中做任何事情来解决客户端的问题。

否则,您可以让您的API将文件放在处理队列中,稍后由另一个软件处理。但这需要另一种架构,因为现在调用者需要在不再连接到API时通知失败成功(或导致一般),因此您需要回调。


0
投票

我有这个代码用于处理大文件(这是一个大型CSV文件上传):

    public async Task<IActionResult> UploadAsync(IFormFile file)
    {
        // Ensure the file has contents before processing.
        if (file == null || file.Length == 0)
            throw new ApiException("Csv file should not be null", HttpStatusCode.BadRequest)
                .AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.BelowMinimumLength, SOURCE); 

        // Ensure the file is not over the allowed limit.
        if (file.Length > (_settings.MaxCsvFileSize * 1024))
            throw new ApiException("Max file size exceeded, limit of " + _settings.MaxCsvFileSize + "mb", HttpStatusCode.BadRequest)
                .AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.ExceedsMaximumLength, SOURCE); 

        // Ensure the file type is csv and content type is correct for the file.
        if (Path.GetExtension(file.FileName) != ".csv" || 
            !Constants.CsvAcceptedContentType.Contains(file.ContentType.ToLower(CultureInfo.InvariantCulture)))
                throw new ApiException("Csv content only accepted").AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.Invalid, SOURCE);

        // Read csv content.
        var content = await file.ReadCsvAsync<OrderCsvResponseDto>() as CsvProcessedResponseDto<OrderCsvResponseDto>;

        await ProcessBulkUpload(content);

        // Return information about the csv file.
        return Ok(content);
    }

    internal async Task ProcessBulkUpload(CsvProcessedResponseDto<OrderCsvResponseDto> content)
    {
         // do some processing...
    }

有web.config设置可以增加文件上传的允许时间,这可能会有所帮助:How to increase the max upload file size in ASP.NET?

如果您的请求超过了允许的最大超时数,则不会按预期将数据返回给调用者!

如果要从C#执行“即发即弃”代码,可以执行以下操作:

public static void FireAndForget(this Task task)
{
    Task.Run(async() => await task).ConfigureAwait(false);
}

使用Javascript:

xhr.onreadystatechange = function() { xhr.abort(); }

AngularJS:

var defer = $q.defer();
$http.get('/example', { timeout: defer.promise }).success(callback);
// [...]
defer.resolve();

一些异步/等待Js的提示:http://2ality.com/2016/10/async-function-tips.html

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