ASP:触发动作服务器端并返回

时间:2016-01-13 11:28:12

标签: c# asp.net

我需要进行一些上传后处理。

用户上传包含大量图片的.zip(通常在100到500之间)。 我需要处理该zip文件以提取,修改和存储图像。

我的问题是这个后处理有点长,因此用户得到HTTP错误500,因为分配用于处理请求的时间结束了。

实际过程:

  1. 用户上传zip文件
  2. 服务器拥有该文件后,处理每个图像
  3. 等待并返回HTTP 200
  4. 我想进行异步后处理:

    1. 用户上传zip文件
    2. 服务器拥有该文件后,触发后处理异步方法
    3. 不要等待并返回HTTP 200
    4. 有可能吗? 有没有更好的方法呢?

      注意:没有代码,因为这只是关于架构的问题

2 个答案:

答案 0 :(得分:1)

只需在另一个帖子中执行后处理。

您可以使用

Task.Factory.StartNew(() => 
{ 
   /*your post-processing code*/ 
   //...etc
   /*when finished, notify user that post-processing has finished, maybe by email*/
});

最好不要让所有请求都创建新线程。如果有很多并发用户,这将是非常糟糕的。而是创建一个“工作”线程,逐个执行“排队任务”。

所以你可以:

private class ProcessItem
{
   //define each task data
}

private static readonly ConcurrentQueue<ProcessItem> queue 
                                      = new ConcurrentQueue<ProcessItem>();

private static Thread worker = new Thread(() =>
{
    while (true) // infinite
    {
        ProcessItem item;
        if (!queue.TryDequeue(out item))
        { //no availble items, wait for an item
           Monitor.Enter(queue); Monitor.Wait(queue); Monitor.Exit(queue);
          continue; //I have been notified, repeat check
        }
        //now process item
    }
});

static YourClass()
{
     worker.Start(); //start the worker at class first-load
}

将项目添加到队列:

queue.Enqueue(item);
Monitor.Enter(queue); 
Monitor.PulseAll(queue); //notifiy the waiting threads
Monitor.Exit(queue);

答案 1 :(得分:1)

我认为最好的方法是使用Async,因为你可能会从主线程池中借用一个线程,这意味着你的服务器可用于处理其他请求的线程较少。现在假设在1-2秒内你有20个zip文件上传,你将从线程池中借用20个甚至更多的线程来处理你的zip文件,这意味着在那个时候你的服务器可以处理20个请求。

这样做的最佳方式是启动一个完全独立的背景进程/应用程序。例如,你可以。

  1. 用户上传zip文件。
  2. 将文件保存到某个位置,然后从您的网络应用程序返回200 ok。
  3. 您的网络应用程序写入和指示,即某种记录到某个地方的adataabase或文件,其中包含有关如何处理zip文件的说明。
  4. 某种应用程序,例如exe可以读取这些指令并处理zip文件并将状态写回数据库或其他东西。
  5. 希望这是有道理的。