简体   繁体   English

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

[英]ASP : trigger action server-side and return

I need to do some upload post-processing. 我需要做一些上传后处理。

The user upload a .zip with a lot of images (usually between 100 and 500). 用户上传的.zip文件包含很多图片(通常在100到500之间)。 I need to process that zip file to extract,modify and store images. 我需要处理该zip文件以提取,修改和存储图像。

My problem is that this postprocessing is a bit long so the user get an HTTP error 500 because the time allocated to process the request is over. 我的问题是此后处理时间有点长,因此用户分配的HTTP错误500很大,因为分配给处理该请求的时间已结束。

The actual process : 实际过程:

  1. User upload the zip file 用户上传zip文件
  2. Once the server has the file, process every images 服务器拥有文件后,处理每个图像
  3. wait and return an HTTP 200 等待并返回HTTP 200

I would like to have an asynchronous postprocessing : 我想进行异步后处理:

  1. User upload the zip file 用户上传zip文件
  2. Once the server has the file, trigger the postprocessing asynchronous method 服务器拥有文件后,触发后处理异步方法
  3. don't wait and return an HTTP 200 不要等待并返回HTTP 200

Is it possible ? 可能吗 ? Is there a better way of doing it ? 有更好的方法吗?

NB: No code because that's just a question about architecture 注意:没有代码,因为那只是关于架构的问题

Just execute your post-processing in another thread. 只需在另一个线程中执行您的后处理即可。

You may use 您可以使用

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

It is much better not to make all requests create new threads. 最好不要让所有请求都创建新线程。 This will be very bad in case with a lot of concurrent users. 如果有大量并发用户,这将是非常糟糕的。 But instead to create a single "worker" thread that executes "queued tasks" one by one. 而是创建一个单独的“工作线程”,该线程一个接一个地执行“排队任务”。

So you can: 所以你可以:

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
}

To add items to queue: 要将项目添加到队列中:

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

I dont think the best way would be to use Async, because you will possibly be borrowing a thread from the main threadpool, which means your server has less threads available to process other requests. 我认为最好的方法不是使用Async,因为您可能会从主线程池中借用一个线程,这意味着您的服务器可用于处理其他请求的线程较少。 Now imagine within in 1-2 secs you have 20 zip files uploaded you will be borrowing 20 or even more threads from the threadpool to process your zip file, which means in that time your server can process 20 fewer requests. 现在,假设您在1-2秒内上传了20个zip文件,那么您将从线程池中借用20个甚至更多线程来处理您的zip文件,这意味着您的服务器在那时可以减少20个请求。

The best way for doing this would be to kick off a completely seperate Background process/App. 最好的方法是启动一个完全独立的后台进程/应用程序。 For example you might. 例如,您可能会。

  1. User upload the zip file. 用户上传zip文件。
  2. Save the file to some location and return from your web app with 200 ok. 将文件保存到某个位置,然后单击确定200从Web应用返回。
  3. Your web app writes and instruction ie some sort of record to adataabase or a file somewhere, containing the instructions on how to process the zip file. 您的Web应用程序向数据库或某处的文件写入和指示(即某种记录),其中包含有关如何处理zip文件的说明。
  4. some sort of app for example an exe can read these instructions and process the zip file and write the status back to database or something. 某种应用程序,例如exe可以读取这些说明并处理zip文件,并将状态写回到数据库或其他内容。

Hope this makes sense. 希望这是有道理的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM