【问题标题】:Web API allow only single async taskWeb API 只允许单个异步任务
【发布时间】:2014-03-07 23:30:19
【问题描述】:

仅处理单个异步操作的正确方案是什么?例如,我需要导入大文件,在导入时我需要禁用该选项以确保不会触发第二次导入。

想到什么:

[HttpPost]
public async Task<HttpResponseMessage> ImportConfigurationData()
{
    if (HttpContext.Current.Application["ImportConfigurationDataInProcess"] as bool? ?? false)
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Task still running");

    HttpContext.Current.Application["ImportConfigurationDataInProcess"] = true;

    string root = HttpContext.Current.Server.MapPath("~/App_Data");
    var provider = new MultipartFormDataStreamProvider(root);
    await Request.Content.ReadAsMultipartAsync(provider);

    //actual import

    HttpContext.Current.Application["ImportConfigurationDataInProcess"] = false;
    Request.CreateResponse(HttpStatusCode.OK, true)
}

但这似乎是非常硬编码的解决方案。什么是正确的处理方法? 另一件事它在客户端无法正常工作,它仍在等待响应。那么用户是否有可能只是将该文件发送到服务器而不是等待未点亮它会完成但在文件发送到服务器后重新加载页面而无需等待await 的东西将完成。

【问题讨论】:

    标签: c# asp.net asynchronous asp.net-web-api async-await


    【解决方案1】:

    async does not change the HTTP protocol(正如我在博客中解释的那样)。因此,每个请求您仍然只能得到一个响应。

    正确的解决方案是将工作的“令牌”(和导入数据)保存在一些可靠的存储(例如 Azure 表/队列)中,并有一个单独的处理后端来执行实际的导入。

    ImportConfigurationData 操作随后会检查该数据是否已经存在令牌,如果找到,则会对请求进行故障处理。

    【讨论】:

    • 感谢您的回答。但我不会改变协议。我只想以某种方式启动任务并发送一些错误响应,如果该请求在任务仍在进行中时被调用。
    • 我理解并且可以接受该解决方案带来的风险。而且我无法仅为此目的设置 Azure。我试过 Task.Factory.StartNew(async () => //一些导入代码);但它不喜欢 async() 之后 await Request.Content.ReadAsMultipartAsync(provider);似乎我的任务附加到主线程
    • @Vladimirs:我的帖子的重点是async 不会更改 HTTP 协议。如果您使用的是 HTTP,那么每个请求只会得到一个响应。因此,如果您想在导入完成之前向客户端返回响应,那么您将需要一个更复杂的解决方案。 Azure 只是可靠存储的一个例子;您不必使用 Azure 来解决这个问题。
    • 所以基本上你建议不要将任务状态存储在 HttpContext.Current.Application 中,而是存储在 DB 中。或者您的意思是也在 Azure 上运行任务?
    • @Vladimirs:是的,数据库是可靠的存储,所以没问题。
    猜你喜欢
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2022-11-18
    相关资源
    最近更新 更多