WEB耗时任务的处理方案

最近有一个需求,从网页上传一个文本包到后台处理,处理时长可能在几分钟到几十分钟。原来的方案就是直接接收一个ajax请求处理数据,然后返回。遇到的问题是:经过十几分钟的处理后,后台返回结果到前端,前端收不到该结果了。我想应该是http连接超时了,除非长连接,没有哪个请求可以这样无限制地等待。于是着手改进方案,先说一下思路:

        1.前端上传文件到后台后,后台开启一个子线程处理耗时任务,主线程直接返回结果给前端,当前请求结束,无须等待子任务的处理结果。注意这里的返回结果只是表示文件上传成功,是一个阶段性的结果而已。

        2.前端开启一个轮询,每隔一秒查一下当前任务的处理进度,直到任务处理结束。

        回答一下这个思路中的几个关键点

        1.轮询检查的依据是什么?后台根据什么来知道当前是谁在查询?答案:Session.对Session不太了解的同学可以再做一下功课,这里不展开。

        2.主线程和新开的子线程之间是需要交换数据的,包括子线程和查询线程之间也是需要交换数据的,这个交换数据是用什么来实现?答案:HttpRuntime Cache,对这个不熟悉的也做一下功课,这里简单理解为就是一块可以共享数据的内存区域。

        好了,思路和关键点都解决了,这里再来贴一下关键点的代码,让大家有一个更清晰的认识

        1.开启子线程       

//sessionid是作为一个参数传到子线程里面去的,我们保存数据到cache中是以sessionid+关键字的形式来做key值,而session值是不能在子线程中直接获取的,所以传进去

String sessionId = Session.SessionID;

ThreadProc threadProc = new ThreadProc(sessionId);

Thread thread = new Thread(new ThreadStart(threadProc.process));

thread.IsBackground = true;

thread.Start();

          子线程类:         

class ThreadProc{

      private string sessionId = "";

      public ThreadProc(string sessionId){

             this.sessionId = sessionId;

      }

      public void process(){

             //这里具体处理耗时任务

             //保存结果

             cache.WriteCache<Result>(result,sessionId+"result");

      }

} 

 

            2.cache的存取

            Cache cache = new Cache();

            //读取

             Result result = cache.GetCache<Result>(sessionId+"result");

            //保存

            cache.WriteCache<Result>(result,sessionId+"result");

             这里Cache类是对原始HttpRuntime Cache的一次封装,示例如下             

public class Cache{

       private static System.Web.Caching.Cache cache = HttpRuntime.Cache;

       public T GetCache<T>(string cacheKey) where T:class{

               if(cache[cacheKey]  != null){

                       return (T)cache[cacheKey];

                }

                return default(T);

        }

        public void WriteCache<T>(T value,string cacheKey) where T:class{

                cache.Insert(cacheKey,value,null,DateTime.Now.AddMinute(10),System.Web.Caching.Cache.NoSlidingExpiration);

        }

}

                3.轮询处理                   

public string CheckProcState(){

       string sessionId = Session.SessionID;

       Cache cache = new Cache();

       Result result = cache.GetCache<Result>(sessionId+"result");

       return result.ToJson();

}

 

            好啦,大体过程就是这样了,欢迎大家指正,也欢迎讨论其他处理长耗时任务的可具体实施的思路。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值