ajax定时轮询请求配合.net后台的多线程处理方法的应用

该方法主要针对的情况是:后台数据处理时间较长,前台请求在长时间未接收到后台的返回值时,会失去连接。因此可以使用ajax轮询定时向后台请求数据。

后台的多线程指的是将计算量比较大的部分放到子线程中进行处理,主线程依旧运行,并且返回结果(此结果不需要等待子线程跑完,只是先让前台得到响应)。

 

前台轮询部分:

ajax定时轮询请求配合.net后台的多线程处理方法的应用
  var getting = {
            type: "Get",
            url: "xxx/xxx",
            data: {},
            success: function (data: any) {                              
                if (data.length == 0) {                                                           
                   //此处为后台返回值为空data表明子线程为跑完
                    setTimeout(function () { $.ajax(getting); }, 10000);//10秒后定时发送请求
                } 
                else {
                   //这里是后台子线程跑完的处理                                                                                                                                               
                             
                }
            }
        }

        $.ajax(getting);
View Code

 

后台多线程:

 

 //主线程
        [HttpPost("[action]")]
        public List<ResultFilters> ExonCompare(string sampleid,string gene,string enstId,int select_page=1,int tab_page=0)
        {           
            //本地测试代码
            List<string> inputSeq = new List<string>();
            var path = @"d:\_txt";
            using (var sr = new StreamReader(new FileStream(path, FileMode.Open)))
            {
                var line = sr.ReadLine();
                var a = line.Split("\t");
                line = sr.ReadLine();
                while (line != null && line != "")
                {
                    var arr = line.Split('\t');
                    inputSeq.Add(arr[7]);
                    line = sr.ReadLine();
                }
            }

            List<ThreadParam> paramList = new List<ThreadParam>();
            ThreadParam threadParam = new ThreadParam();
            threadParam.ListSeqPath = sampleid + "_" + gene + "_" + enstId + "_" + select_page + "_" + tab_page+"_";
            threadParam.InputSeq = inputSeq[tab_page];           
            paramList.Add(threadParam);
            List<ResultFilters> rfs = new List<ResultFilters>();
            ParameterizedThreadStart threadList = new ParameterizedThreadStart(OtherObject);
            Thread t = new Thread(threadList);                
            t.Start(paramList);                   
            return rfs;
        }
 public void OtherObject(object paramObj)
        {
 //paramObj在子线程中只能以object对象来传参,对象中可包含多个参数
            List<ThreadParam> parm = (List<ThreadParam>)paramObj;
            var inputSeq = parm[0].InputSeq;
            var listSeqPath = parm[0].ListSeqPath;        
                                                 
            try {
               //耗时接口这里交给子线程
                var list = _IExonsLibService.RNACompare_E(inputSeq, 0.98f).ToList();
                List<ResultFilters> rfs = new List<ResultFilters>();
                if (list.Count==0) {
                    ResultFilters resultFilters = new ResultFilters();
                    resultFilters.FullNameParmPath = listSeqPath;
                    resultFilters.ResultInfo = "未找到匹配序列";
                    rfs.Add(resultFilters);
                    CallBackExonanalysis(rfs);  // 通过委托, 将数据回传给回调函数                   
                }                
                List<ExonViewModel> result = new List<ExonViewModel>();
                foreach (var item in list)
                {
                    ExonViewModel info = new ExonViewModel();
                    info.ResultSeq = item.GetElement(1).ToString().Substring(6);
                    info._id = ObjectId.Parse(item.GetElement(0).ToString().Substring(4));
                    var findseq = _IExonsLibService.FindSeq(info._id);
                    var findinfo = _IExonsLibService.FindExonInfo(findseq.InfoId);
                    info.FindSeq = findseq.Seq;
                    info.Info_id = findinfo._id;
                    info.StartExonPos = int.Parse(findinfo.StartCoordinate);
                    info.EndExonPos = int.Parse(findinfo.EndCoordinate);
                    info.GeneId = findinfo.GeneID;
                    info.ExonId = findinfo.ExonID;
                    info.InputSeq = inputSeq;
                    int startComPos = info.ResultSeq.IndexOf("=");
                    info.StartComPos = startComPos;
                    int endComPos = info.ResultSeq.LastIndexOf("=");
                    info.EndComPos = endComPos;
                    //char[] usefulSeq = info.ResultSeq.Substring(startComPos, endComPos - startComPos + 1).ToCharArray();
                    info.EqualsCount = info.EndComPos - info.StartComPos + 1;
                    result.Add(info);
                }              
                var AN = result.OrderBy(p => p.StartComPos).ToList();
                List<List<FilterViewModel>> unios = new List<List<FilterViewModel>>();
                for (int i = 0; i < AN.Count;)
                {

                    List<FilterViewModel> couple = new List<FilterViewModel>();
                    FilterViewModel filter = new FilterViewModel();

                    filter.Seq = AN[i].FindSeq;
                    filter.StartExonPos = AN[i].StartExonPos;
                    filter.EndExonPos = AN[i].EndExonPos;
                    filter.GeneId = AN[i].GeneId;
                    filter.ExonId = AN[i].ExonId;
                    filter.EqualsCount = AN[i].EqualsCount;
                    couple.Add(filter);                   
                    int k = i;
                    for (int j = i + 1; j < AN.Count; j++)
                    {
                        if (AN[k].EndComPos < AN[j].StartComPos)
                        {
                            FilterViewModel filter2 = new FilterViewModel();
                            filter2.Seq = AN[j].FindSeq;
                            filter2.StartExonPos = AN[j].StartExonPos;
                            filter2.EndExonPos = AN[j].EndExonPos;
                            filter2.GeneId = AN[j].GeneId;
                            filter2.ExonId = AN[j].ExonId;
                            filter2.EqualsCount = AN[j].EqualsCount;
                            couple.Add(filter2);
                            k = k + 1;
                        }

                    }
                    unios.Add(couple);
                    i = i + 1;
                }
                List<CountWork> Ac = new List<CountWork>();
                foreach (var items in unios)
                {
                    CountWork n = new CountWork();
                    foreach (var m in items)
                    {
                        n.Allcount += m.EqualsCount;
                    }
                    Ac.Add(n);
                }
                //List<ResultFilters> rfs = new List<ResultFilters>();
                if (Ac.Count != 0)
                {
                    var max = Ac.Select(p => p.Allcount).Max();
                    var order = Ac.FindIndex(x => x.Allcount == max);
                    var resultFilter = unios[order].OrderBy(p => p.StartExonPos).ToList();
                    var q = resultFilter.GroupBy(x => x.GeneId).ToList();
                    foreach (var n in q)
                    {
                        ResultFilters resultFilters = new ResultFilters();
                        resultFilters.GeneId = n.Key;
                        var maxm = n.Select(p => p.EndExonPos).Max();
                        var minm = n.Select(x => x.StartExonPos).Min();
                        resultFilters.SeqLength = maxm - minm + 1;
                        resultFilters.filterInfo = n.ToList();
                        resultFilters.FullNameParmPath = listSeqPath;
                        rfs.Add(resultFilters);
                        CallBackExonanalysis(rfs);  // 通过委托, 将数据回传给回调函数                        
                    }
                }
                else
                {
                    rfs.Add(null);
                    CallBackExonanalysis(rfs);  // 通过委托, 将数据回传给回调函数                   
                }              
            } catch {
                //List<ResultFilters> rfs = new List<ResultFilters>();               
                //CallBackExonanalysis(rfs);  // 通过委托, 将数据回传给回调函数        
            }
           
                       
        }       

回调函数处理子线程的结果(此处是子线程的回调函数,处理结果可以写入txt文件):

 public void CallBackExonanalysis(List<ResultFilters> rfs)
        {
           
           ... 
                         
        }

再通过txt文件转化为list,返回给前台

 //读取文本文件转换为List 
        [HttpGet("[action]")]
        public List<ResultFilters> ReadTextFileToList(string sampleid, string select_gene, string enstId, int select_page = 1, int tab_page = 0)
        {
           ...
           ...
           return list;
        }

 

最后前台可额外用一个单次请求首先请求这个ReadTextFileToList,如果list为空表明文件没有内容(也就是后台还未处理过数据)那么就调用主线程请求,否则不做任何处理。

 //仅请求一次判断文件是否有结果
        Axios.get('api/ExonCom/ReadTextFileToList', { params: { sampleid: query.sampleid, select_gene: query.select_gene, enstId: query.enstId, select_page: query.select_page, tab_page: _this.tab_page } })
            .then(function (res: any) {
                if (res.data.length == 0) {
                    //没结果
                    _this.ExonCompareFlag = true;
                    if (_this.ExonCompareFlag == true) {
                        _this.requestExonCompare();
                    }
                } else {                   
                    _this.ExonCompareFlag = false;
                }
            })
            .catch(function (error) {
                alert(error);
            });
 requestExonCompare() {
        const _this = this;
        var query = _this.$route.query;
        let formData = new FormData();
        let config = {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        }
        formData.append("sampleid", query.sampleid);
        formData.append("gene", query.select_gene);
        formData.append("enstId", query.enstId);
        formData.append("select_page", query.select_page);
        formData.append("tab_page", _this.tab_page.toString());
        
        Axios.post('api/ExonCom/ExonCompare', formData, config).then(function (res:any) {
            //console.log(res);            
        });         
    } 

 

上一篇:综合运用DID, RD的一篇准自然实验, 看看RFS上如何做的相关实证?


下一篇:Linux RPS/RFS 实现原理浅析