简体   繁体   English

具有实时接口进度状态的Ajax服务器进程?

[英]Ajax server process with live interface progress status?

I have a process that retrieves html from a remote site and parses it. 我有一个从远程站点检索html并对其进行解析的过程。 I pass several URL's into the method, so I would like to ajaxify the process and give a screen notification each time a URL completes parsing. 我将几个URL传递给该方法,因此我想简化该过程并在每次URL完成解析时发出屏幕通知。 For example, this is what I am trying to do: 例如,这就是我想要做的:

List<string> urls = ...//load up with arbitary # of urls

foreach (var url in urls)
{
    string html = GetContent(url);
    //DO SOMETHING
    //COMPLETED.. SEND NOTIFICATION TO SCREEN (HOW DO I DO THIS)
}

public static string GetContent(string url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";

    using (var stream = request.GetResponse().GetResponseStream())
    {
        using (var reader = new StreamReader(stream, Encoding.UTF8))
        {
            return reader.ReadToEnd();
        }
    }
}

In each iteration in the loop, I want to show the URL was completed and moving on to the next one. 在循环的每个迭代中,我想显示URL已完成并转到下一个URL。 How can I accomplish this? 我该怎么做?

The first thing you need to worry about is the fact (I'm assuming) that you're running a potentially long-running operation in ASP.NET code. 您需要担心的第一件事是事实(我假设)是您正在ASP.NET代码中运行可能长时间运行的操作。 This will become a problem when you run in to IIS timeouts. 当您运行IIS超时时,这将成为一个问题。 (By default, 90 seconds.) Assume you're processing ten URLs, each of which takes 15 seconds to complete reader.ReadToEnd() – your code will time out and get killed after the sixth URL. (默认情况下为90秒。)假设您正在处理十个URL,每个URL需要15秒才能完成reader.ReadToEnd() –您的代码将超时,并在第六个URL之后被杀死。

You might be thinking "I can just crank up the timeout," but that's not really a good answer; 您可能会想“我可以加快超时时间”,但这并不是一个很好的答案。 you're still under time pressure. 您仍然面临时间压力。

The way I solve problems like this is to move long-running operations into a stand-alone Windows Service, then use WCF to communicate between ASP.NET code and the Service. 我解决此类问题的方法是将长时间运行的操作移至独立的Windows Service中,然后使用WCF在ASP.NET代码和Service之间进行通信。 The Service can run a thread pool that executes requests to process a group of URLs. 该服务可以运行一个线程池,该线程池执行处理一组URL的请求。 ( Here's an implementation that allows you to queue work items.) 这是一个允许您将工作项目排队的实现 。)

Now, from your web page, you can poll for status updates via AJAX requests. 现在,您可以从网页上通过AJAX请求轮询状态更新。 The handler in your ASP.NET code can use WCF to pull the status information from the Service process. ASP.NET代码中的处理程序可以使用WCF从Service进程中提取状态信息。

A way to do this might be to assign each submitted work unit a unique ID and return that ID to the client. 一种方法是为每个提交的工作单位分配一个唯一的ID,然后将该ID返回给客户端。 The client can then poll for status by sending an AJAX request for the status of work unit n . 然后,客户端可以通过发送AJAX请求来查询状态,以获取工作单元n的状态。 In the Service, keep a List of work units with their statuses ( lock ing it as appropriate to avoid concurrency problems). 在服务中,保留工作单元List及其状态(适当lockList以避免并发问题)。

public class WorkUnit {
   public int ID { get; set; }
   public List<string> URLs { get; set; }
   public int Processed { get; set; }
}

private var workUnits = new List<WorkUnit>();

private void ExecuteWorkUnit(int id) {
    var unit = GetWorkUnit(id);

    foreach (var url in unit.URLs) {
         string html = GetContent(url);
         // do whatever else...
         lock (workUnits) unit.Processed++;
    }
}

public WorkUnit GetWorkUnit(int id) {
    lock (workUnits) {
         // Left as an exercise for the reader
    }
}

You'll need to fill in methods to add a work unit, return the status of a given work unit, and deal with the thread pool. 您需要填写方法来添加工作单元,返回给定工作单元的状态以及处理线程池。

I've used a similar architecture with great success. 我使用了类似的架构,并取得了巨大的成功。

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

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