Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有实时界面进度状态的Ajax服务器进程?_C#_.net_Asp.net_Ajax_Asp.net Ajax - Fatal编程技术网

C# 具有实时界面进度状态的Ajax服务器进程?

C# 具有实时界面进度状态的Ajax服务器进程?,c#,.net,asp.net,ajax,asp.net-ajax,C#,.net,Asp.net,Ajax,Asp.net Ajax,我有一个从远程站点检索html并对其进行解析的过程。我将几个URL传递到该方法中,因此我希望在每次URL完成解析时对该过程进行ajaxify,并给出一个屏幕通知。例如,这就是我试图做的: List<string> urls = ...//load up with arbitary # of urls foreach (var url in urls) { string html = GetContent(url); //DO SOMETHING //COMP

我有一个从远程站点检索html并对其进行解析的过程。我将几个URL传递到该方法中,因此我希望在每次URL完成解析时对该过程进行ajaxify,并给出一个屏幕通知。例如,这就是我试图做的:

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();
        }
    }
}
列出URL=…//加载任意的URL
foreach(url中的变量url)
{
字符串html=GetContent(url);
//做点什么
//已完成..向屏幕发送通知(如何执行此操作)
}
公共静态字符串GetContent(字符串url)
{
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(url);
request.Method=“GET”;
使用(var stream=request.GetResponse().GetResponseStream())
{
使用(var reader=newstreamreader(stream,Encoding.UTF8))
{
返回reader.ReadToEnd();
}
}
}

在循环中的每个迭代中,我希望显示URL已完成,并继续下一个迭代。如何才能做到这一点?

您首先需要担心的是(我假设)您正在ASP.NET代码中运行一个可能会长期运行的操作。当您遇到IIS超时时,这将成为一个问题。(默认情况下为90秒。)假设您正在处理10个URL,每个URL需要15秒才能完成
reader.ReadToEnd()
–您的代码将超时,并在第六个URL之后被删除

你可能会想“我可以加快超时时间”,但这不是一个好答案;你仍然面临时间压力

我解决此类问题的方法是将长期运行的操作移动到独立的Windows服务中,然后使用WCF在ASP.NET代码和服务之间进行通信。该服务可以运行线程池,该线程池执行处理一组URL的请求。(允许您对工作项进行排队。)

现在,从您的web页面,您可以通过AJAX请求轮询状态更新。ASP.NET代码中的处理程序可以使用WCF从服务进程中提取状态信息

一种方法是为每个提交的工作单元分配一个唯一的ID,并将该ID返回给客户端。然后,客户端可以通过发送工作单元状态的AJAX请求来轮询状态。在服务中,保留工作单元的
列表及其状态(
锁定
以避免并发问题)

公共类工作单元{
公共int ID{get;set;}
公共列表URL{get;set;}
公共整数处理{get;set;}
}

private var workUnits=new List();
私有void ExecuteWorkUnit(int-id){
var unit=GetWorkUnit(id);
foreach(单位url中的变量url){
字符串html=GetContent(url);
//做任何其他事情。。。
锁定(工作单元)单元。已处理++;
}
}
公共工作单元GetWorkUnit(内部id){
锁(工作单元){
//留给读者作为练习
}
}
您需要填写方法来添加工作单元、返回给定工作单元的状态以及处理线程池

我使用了类似的体系结构,并取得了巨大成功

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
    }
}