小弟最近还是在做那个关于WEB GPS的页面````用了常规方法,可以使10辆车左右在页面根据实时数据更新页面,但是客户要求需要1W辆车同时在地图上```````我刚把车加到1000辆`````````当我实时监听数据的时候  页面就发生未响应,我每1秒发送一个请求  得到实时数据`````在返回回来显示在页面上````但是现在 当我第一个请求还在操作中时,又开始发送第二个请求了,问了下公司的老前辈,他们说要采用多线程  什么异步通信,现在纠结了`````完全不知道该怎么处理`````先上下自己的代码`````望各位高淫赐教 赐教
前台:function Retime()
{
    var jt = document.getElementById('Button2').value;
    if(jt=="启动实时监听")
    {
        document.getElementById('Button2').value='停止实时监听';
        timer1 =setInterval('fa()',2000);
    }
    else
    {
        document.getElementById('Button2').value='启动实时监听';
        clearInterval(timer1);
    }
}
function fa()
{
     req=GetXmlHttpRequest();
     
     url ="../content/RealTime.aspx?qs=2";
     req.open("GET", url, true);
     
     req.onreadystatechange = qu;//服务器处理响应后由这个函数响应
     req.send(null);
     
}
function qu()
{
   if (req.readyState == 4)
   {
       if (req.status == 200)
       {    
            for(var i=0;i<req.responseText.split('\n')[1];i++)
           {
                var x=req.responseText.split('\n')[0].split('\t')[i].split('\r')[1].split(',')[0].split('(')[1];           
                var y=req.responseText.split('\n')[0].split('\t')[i].split('\r')[1].split(',')[1].split(')')[0]; 
                mapObj.erMoveTo(req.responseText.split('\n')[0].split('\t')[i].split('\r')[0], new MLngLat(x,y));
           }
       }
    }
    
}后台,  老是在那个FOR循环里卡死掉`````
                string url = ConfigurationManager.ConnectionStrings["SDB1"].ConnectionString;
                object objRtn = RemotingServices.Connect(typeof(GpsDb.GpsData), url);
                GpsDb.GpsData gd = objRtn as GpsDb.GpsData;
                DataSet ds = gd.GET_DATA_DB(sql);//
                String s="";
                for (int a = 0; a < ds.Tables[0].Rows.Count; a++)//1k
                {
                        s += ds.Tables[0].Rows[a]["Deviceid"].ToString();
                        s += "\r" + ds.Tables[0].Rows[a]["geo_position"].ToString()+"\t";
                }
                Response.Write(s+"\n");
                Response.Write(ds.Tables[0].Rows.Count.ToString());

解决方案 »

  1.   

    地图的JS的refresh不要太频繁。
    我做类似项目,大概是每1分钟回传一次。
    你的数据量大(1W辆车)每1秒,对服务器压力太大。就算你用了AJAX异步传输,也会出问题的,延迟大!
    建议加长回传间隔时间
      

  2.   


    频繁读取数据库,对服务器也是一个大负担。
    较好的做法是直接从GPS的服务商的服务器那边得到数据后,在客户端进行解析。
      

  3.   

    刚才又询问了下``````被骂了``````然后呢`````说 还是必须每0。5秒刷新一次`````然后给了少部分代码
    ``````还是看不懂``````求助``````老大说  如果我半个月做不出来要卷铺盖走人```````这次真的急了```` protected void Page_Load(object sender, EventArgs e)
            {
                System.ComponentModel.BackgroundWorker ff = new System.ComponentModel.BackgroundWorker(); if (!ff.CancelAsync.RunWorkerCompleted{ff.RunWorkerAsync}.r.CancellationPending) { 787}他说用这个 重载DOWORK 方法
      

  4.   

    如果lock的话很慢。。多线程弄过么?
      

  5.   

    异步通信的底层实现,http://wenku.baidu.com/view/2f6dc61bff00bed5b9f31db2.html
      

  6.   

    HIpity  谢谢你的回答  不过那是AJAX  不是我想要的多线程`````
      

  7.   

    你老大在忽悠你吧,就算用backgroupworker取到数据,在在线地图上加1万个点也死定了。我很怀疑你老大是不是真的知道解决方法,对,用异步通信是肯定的,但问题的关键是应该用静态变量保存接收到的数据,使用的时候从静态变量获取,而不是向服务器请求。
    具我的经验,大部分人都不知道这个方法,这不是个新手能想得出来的,你老大要么是想早你做炮灰,要么想整整你。
      

  8.   

    啊,我看他开了WINFORM的项目   然后就是显示正在读取的什么东西  那个东西一直在不停的刷新````他说这就是多线程  哎   烦死了```
      

  9.   

    是Winform还是Web?winform简单些,但道理其实是一样的。
    Winform可以是任意变量,你只需要在BackgroundWorker的异步方法中获取数据保存到变量,在地图里使用即可。
      

  10.   

    我是WEB,用的三层嘛  他就给了我1个DLL文件  通过DLL文件 读信息  我只负责把信息收集起来 显示在页面上```
      

  11.   

    你们头用winform实现的,简单一些。
    你做B/S的,有点困难。首先JS地图要重绘1W个点,在效率上就很难实现。
    JS是客户端行为,IE是轻量级的,跟C/S程序相比 很困难
      

  12.   

    AJAX实现异步通讯,这样才能使得页面不会一直等待未完成的服务器响应。
    而是流程的继续往下走。
    如果你页面没有AJAX,就算你是多线程,你页面如何获取结果?还有,你们老大很有可能自己都想不出来解决方案。
    我在学院做过这个,4S店的呼叫中心的地图可以实时显示当前呼叫到呼叫中心的车主动态位置信息。当时模拟的是2000个车主同时出现问题,需要呼叫中心帮忙。
    一开始客户要求是实时的,1s刷新一次。
    但是后来发现服务器承受能力/网络带宽/客户端浏览器响应能力等限制,改为了1分钟刷新一次。否则会出现浏览器假死...
      

  13.   

    再次感谢``````你可以看下我的代码吗?  我实现了AJAX的 ```````我知道局部刷新 我现在相当于是要的并行计算```我觉得快接近了```还差点点`````
      

  14.   

    用 SOCKET 每个车定一个结构,用 SOCKET SERVER 与 GPS 通信(不间断),当发生位置变化时,用 PUSH 的方法把一个车的ID、坐标(结构)传回到客户端(可以是 APPLICATION 也可以是 WEB(SILVERLIGHT FLEX等),在客户端只是要用协议式的解析方式就可以,也就是判断协议处理,比如 A车的坐标变化等,可扩展的思路为,如果客户端的视口是固定的,或是有范围的,服务端在 PUSH 坐标时,可以判断车是不是在视口里,如果不在,可以不发送信息,当客户端移动视口时,再刷新当前视口区域内的车辆信息,当然大批刷新就可以直接通过 WEBSERVICE方式了
      

  15.   

    这个方法可行。
    但是因为JS地图可以放大缩小。当客户把地图比例缩小后....显示整个省份/城市...那么数据量就爆了。
    当时我做的时候,就困在这个问题。锁住地图比例也不方便客户查看路线信息
    判断车是否在地图当前视窗,可以先获取地图的4个顶点经纬度,然后跟车的经纬度进行判断。
    从1W的车经纬度中筛选出需要的显示在地图上。这样信息量会减少很多。做成silverlight/flash形式 就比较麻烦了...我没做过...LZ也没那个精力重新研究吧?
      

  16.   

    如果地图视窗内必须显示1W量车。
    那么可以将经纬度差不多的(某段街道)上的车group起来。显示一个点,旁边注释几辆车...
    毕竟地图里显示1W量车。谁看的过来啊
      

  17.   

                string url = ConfigurationManager.ConnectionStrings["SDB1"].ConnectionString;
                object objRtn = RemotingServices.Connect(typeof(GpsDb.GpsData), url);
                GpsDb.GpsData gd = objRtn as GpsDb.GpsData;
                DataSet ds = gd.GET_DATA_DB(sql);//
                System.Text.StringBuilder s = new System.Text.StringBuilder();
                foreach (System.Data.DataRow row in ds.Tables[0].Rows)
                {
                    s.Append(row["Deviceid"].ToString());
                    s.Append("\r");
                    s.Append(row["geo_position"].ToString());
                    s.Append("\t");
                }
                s.Append("\n");
                s.Append(ds.Tables[0].Rows.Count.ToString());
                Response.Write(s.ToString());试试把后台的String改为StringBuilder,如果知道Deviceid与geo_position的下标,建议改为下标取值。
      

  18.   

    js程序不停的操作字符串的效率问题也很严重
    function qu()
    {
       if (req.readyState == 4)
       {
           if (req.status == 200)
           {    
                var text=req.responseText.split('\n'),xys=text[0].replace(/[\(\)\,]/g,'\r').split('\t');
                for(var i=0,c=text[1];i<c;i++)
               {
                    var xy=xys[i].split('\r');
                    mapObj.erMoveTo(xy[0], new MLngLat(xy[2],xy[3]));
               }
           }
        }    
    }
      

  19.   

    你们老大不懂什么叫网站程序吧,网站处理客户端请求本来就是多线程的。虽然js没有真正意义上的多线程,但是
    req.open("GET", url, true);
    这个异常请求相当于前后台都是多线程了。
      

  20.   

    你的ds.Tables[0].Rows.Count记录里有多少条数据?
    如果是有一万条数据的话肯定麻烦了,不要说要操作数据库,你不操作数据库就只打印一个\r\n你就够受了。
    你这个的问题不在于js页在这个web页面。
    ds.Tables[0].Rows.Count记录的条数是不是固定的?
      

  21.   

    提供一个我的思路:
    1.设置一个button 点击时开启实时同步车辆信息,且js地图只能拖动,但是不能放大缩小比例(可以控制一定范围)
    2.点击button关闭实时同步后,可以放大缩小地图比例
    3.地图的视窗只重绘经纬度在当前窗口内的车辆信息。
      

  22.   

    我给你的建议是:在js里面,分成100次来请求aspx里的内容,这样每一次aspx就只用执行100条记录了。
    你们老大那是扯蛋的话,基于IIS的程序一秒内就算不操作数据库,不管他是多线程还是单线程,只让他显示一万个1 办到的可能性都不大。
      

  23.   

    不能沉啊,或者换个模式
    ComponentModel.BackgroundWorker    这个东西该怎么用``````
           比如那个什么DOWORK 这些`````
      

  24.   


    江湖风波恶,估计你的老大也不是很懂技术细节,你问了反而起了反效果,结果被骂了。Mark!!!!!!!!!!
      

  25.   

    2天了   我还一直在刷新  求高淫讲解下   那个该怎么用else if(qx.Equals("3"))
                {
                    System.ComponentModel.BackgroundWorker ff = new System.ComponentModel.BackgroundWorker();
                    ff.DoWork += new DoWorkEventHandler(Dowork1);
                    ff.WorkerSupportsCancellation = true;
                    ff.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Jieshu);
                    ff.RunWorkerAsync();
                }
      

  26.   


    我这么做了的  我用了个BUTTON 来控制是否开启实时跟踪,关键不是在前台,是在后台处理数据那个环节太慢了```
      

  27.   

    如果确定是后台处理数据太慢,可以采用生产者模式
    using System;
    using System.Configuration;
    using System.Data;namespace GpsDb
    {
        public class GetGpsData
        {
            private string url = ConfigurationManager.ConnectionStrings["SDB1"].ConnectionString;
            private string ResponseWrite = null;
            public string responseWrite
            {
                get
                {
                    string value = ResponseWrite;
                    if (value != null)
                    {
                        System.Threading.Monitor.Enter(this);
                        ResponseWrite = null;
                        System.Threading.Monitor.Pulse(this);
                        System.Threading.Monitor.Exit(this);
                    }
                    return value;
                }
            }
            public GetGpsData()
            {
                new System.Threading.Thread(new System.Threading.ThreadStart(CreateData)).Start();
            }
            private void CreateData()
            {
                string sql = "???";
                while (true)
                {
                    System.Threading.Monitor.Enter(this);
                    try
                    {
                        if (ResponseWrite == null)
                        {
                            object objRtn = System.Runtime.Remoting.RemotingServices.Connect(typeof(GpsDb.GpsData), url);
                            GpsDb.GpsData gd = objRtn as GpsDb.GpsData;
                            DataSet ds = gd.GET_DATA_DB(sql);//不知你的sql是从哪里来的
                            System.Text.StringBuilder s = new System.Text.StringBuilder();
                            foreach (System.Data.DataRow row in ds.Tables[0].Rows)
                            {
                                s.Append(row["Deviceid"].ToString());
                                s.Append("\r");
                                s.Append(row["geo_position"].ToString());
                                s.Append("\t");
                            }
                            s.Append("\n");
                            s.Append(ds.Tables[0].Rows.Count.ToString());
                            ResponseWrite = s.ToString();
                        }
                        else System.Threading.Monitor.Wait(this);
                    }
                    finally { System.Threading.Monitor.Exit(this); }
                }
            }
            public static readonly GetGpsData getGpsData = new GetGpsData();
        }
    }原来的代码改为
                string data = GetGpsData.getGpsData.responseWrite;
                if (data != null) Response.Write(data);
      

  28.   

    加了个cach,防止异常中止
    using System;
    using System.Configuration;
    using System.Data;namespace GpsDb
    {
        public class GetGpsData
        {
            private string url = ConfigurationManager.ConnectionStrings["SDB1"].ConnectionString;
            private string ResponseWrite = null;
            public string responseWrite
            {
                get
                {
                    string value = ResponseWrite;
                    if (value != null)
                    {
                        System.Threading.Monitor.Enter(this);
                        ResponseWrite = null;
                        System.Threading.Monitor.Pulse(this);
                        System.Threading.Monitor.Exit(this);
                    }
                    return value;
                }
            }
            public GetGpsData()
            {
                new System.Threading.Thread(new System.Threading.ThreadStart(CreateData)).Start();
            }
            private void CreateData()
            {
                string sql = "???";
                System.Threading.Monitor.Enter(this);
                while (true)
                {
                    if (ResponseWrite == null)
                    {
                        try
                        {
                            object objRtn = System.Runtime.Remoting.RemotingServices.Connect(typeof(GpsDb.GpsData), url);
                            GpsDb.GpsData gd = objRtn as GpsDb.GpsData;
                            DataSet ds = gd.GET_DATA_DB(sql);//不知你的sql是从哪里来的
                            System.Text.StringBuilder s = new System.Text.StringBuilder();
                            foreach (System.Data.DataRow row in ds.Tables[0].Rows)
                            {
                                s.Append(row["Deviceid"].ToString());
                                s.Append("\r");
                                s.Append(row["geo_position"].ToString());
                                s.Append("\t");
                            }
                            s.Append("\n");
                            s.Append(ds.Tables[0].Rows.Count.ToString());
                            ResponseWrite = s.ToString();
                        }
                        catch { }
                    }
                    System.Threading.Monitor.Wait(this);
                }
                System.Threading.Monitor.Exit(this);
            }
            public static readonly GetGpsData getGpsData = new GetGpsData();
        }
    }
      

  29.   

    掉了一个else可能导致停止生产,再改一下
    using System;
    using System.Configuration;
    using System.Data;namespace GpsDb
    {
        public class GetGpsData
        {
            private string url = ConfigurationManager.ConnectionStrings["SDB1"].ConnectionString;
            private string ResponseWrite = null;
            public string responseWrite
            {
                get
                {
                    string value = ResponseWrite;
                    if (value != null)
                    {
                        System.Threading.Monitor.Enter(this);
                        ResponseWrite = null;
                        System.Threading.Monitor.Pulse(this);
                        System.Threading.Monitor.Exit(this);
                    }
                    return value;
                }
            }
            public GetGpsData()
            {
                new System.Threading.Thread(new System.Threading.ThreadStart(CreateData)).Start();
            }
            private void CreateData()
            {
                string sql = "???";
                System.Threading.Monitor.Enter(this);
                while (true)
                {
                    if (ResponseWrite == null)
                    {
                        try
                        {
                            object objRtn = System.Runtime.Remoting.RemotingServices.Connect(typeof(GpsDb.GpsData), url);
                            GpsDb.GpsData gd = objRtn as GpsDb.GpsData;
                            DataSet ds = gd.GET_DATA_DB(sql);//不知你的sql是从哪里来的
                            System.Text.StringBuilder s = new System.Text.StringBuilder();
                            foreach (System.Data.DataRow row in ds.Tables[0].Rows)
                            {
                                s.Append(row["Deviceid"].ToString());
                                s.Append("\r");
                                s.Append(row["geo_position"].ToString());
                                s.Append("\t");
                            }
                            s.Append("\n");
                            s.Append(ds.Tables[0].Rows.Count.ToString());
                            ResponseWrite = s.ToString();
                        }
                        catch { }
                    }
                    else System.Threading.Monitor.Wait(this);
                }
                System.Threading.Monitor.Exit(this);
            }
            public static readonly GetGpsData getGpsData = new GetGpsData();
        }
    }
      

  30.   

    先谢谢楼上的兄弟  生产者模式  StringBuilder?   我看我要回去研究下下 
      

  31.   


    不好意思,是我没有说清楚,我说的分成100次来请求是指同时执行100次(在js端异步同时执行100次)。
    因为你现在的问题出在aspx页面上,是你的aspx页面不能在一秒内完成显示一万个\r\n,只能减少每次aspx显示的数据.所以就只有通过js来想办法了。