zoukankan      html  css  js  c++  java
  • WCF 大数据量如何从服务端传到客户端

    当数据量很大时,想要从服务端传到客户端可能会遇到这几个问题:基础连接意外关闭;内存溢出;或时间过长。

    下面是我在项目中实现客户端导出txt文件时解决方法。txt有150M左右。

    namespace XSGLSRV900 //服务端接口实现
    {
        public class XSGLService : IXSGLService
        {
    
    //这些变量只能是静态的,如果是非静态的,在客户端每一次调用服务端都认为是新建一个服务对象,这些值将不再能读取到。关于WCF服务端的三种模式可参考http://www.cnblogs.com/tyb1222/archive/2012/10/12/2721252.html
    //这样静态的是有缺陷的,对所有客户端建立的服务端都用这些静态变量,一旦某一个用户使其值改变即便前一个用户还没读取完List值也是不管的,没找到更好的解决办法 private static List<StringBuilder> LStringBuilder = new List<StringBuilder>(); private static int Count = 0; private static int Cur_INX = 0; public int BFBHDDSQLQuery_txt(string sSQL,ref List<string>Datas ,ref List<String> OutERROR) { int iERROR = 0; DataSet ds = null; List<string> exERROR = new List<string>(); //这里要使用StringBuilder,不能用string类型的,以为没对string进行一次操作都会在内存中新建一个对象,如果频繁操作很费时间。 //这里在new时需要用带餐的构造函数,否则默认的长度不够 StringBuilder ss = new StringBuilder(100, Int32.MaxValue); LStringBuilder = new List<StringBuilder>(); Datas = new List<string>(); int iCount = 0; Count = 0; Cur_INX = 0; DbConnection conn = bf.srv.framework.bflib.PubData.GetDbConnection(BHServerPlatform.iBFBHDD); try { CyQuery query = new CyQuery(conn); try { //这里加" " tab键实现txt对齐,再从txt转换成excel时也能保证对其 ss.Append("交易时间 ");//交易时间 ss.Append("结账日期 ");//结账日期 ss.Append("交易流水号 ");//交易流水号 ss.Append("部门代码 ");//部门代码 ss.Append("商标 ");//商标 ss.Append("商品代码 ");//商品代码 ss.Append("收款方式 ");//收款方式 ss.Append("收款金额 ");//收款金额 ss.Append("收款台号 ");//收款台号 ss.Append(" "); query.SQL.Text = sSQL; query.SQL.Text = sSQL; query.Open(); while (!query.Eof) //当Query是IsEmpty时,不能取值 { ss.Append( query.Fields[0].AsDateTime.ToString()+" ");//交易时间 ss.Append(query.Fields[1].AsDateTime.ToShortDateString() + " ");//结账日期 ss.Append(query.Fields[2].AsInteger.ToString() + " ");//交易流水号 ss.Append(query.Fields[3].AsString + " ");//部门代码 ss.Append(query.Fields[4].AsInteger.ToString() + " ");//商标 ss.Append(query.Fields[5].AsString.ToString() + " ");//商品代码 ss.Append(query.Fields[6].AsInteger.ToString() + " ");//收款方式 ss.Append(query.Fields[7].AsDecimal.ToString() + " ");//收款金额 ss.Append(query.Fields[8].AsString + " ");//收款台号 ss.Append( " "); iCount += 1; //这里要把字符串分开成若干个,否则在服务端往客户端传输时会因为数据量太大而报错,连接意外关闭,分成若干个,在客户端一段段读取不会有这个问题就 if (iCount %100000==0) { Count++; LStringBuilder.Add(ss); //Datas.Add(ss.ToString()); //ss.Clear(); ss = new StringBuilder(100, Int32.MaxValue); } query.Next(); } if (iCount % 100000 != 0) { Count++; LStringBuilder.Add(ss); //ss.Clear(); ss = new StringBuilder(100, Int32.MaxValue); } if (iCount > 0) { //chars = new char[ss.Length]; //ss.CopyTo(0, chars, 0, ss.Length); } query.Close(); } catch (Exception e) { iERROR = 1; BHServerPlatform.WriteErrorLog(e.GetType().ToString() + "," + e.StackTrace + ":" + query.SqlText); exERROR.Add(e.Message); } } catch (Exception e) { iERROR = 1; exERROR.Add(e.Message); } finally { conn.Close(); } OutERROR = exERROR; return iERROR; } public String GetStringBuilder() { if (Cur_INX < Count) { Cur_INX++; return LStringBuilder[Cur_INX-1].ToString(); } else return ""; } public bool GetString() { if (Cur_INX < Count) { return true; } else return false; } }
    }
     
            private void btn_DC_Click(object sender, RoutedEventArgs e)//客户端实现导出txt
            {
                Microsoft.Win32.SaveFileDialog MysaveFileDialog = new Microsoft.Win32.SaveFileDialog();
                string MyExpName = "txt";
                string fileName = txt_DC.Text.Trim();
                string strPath = Environment.CurrentDirectory;
                MysaveFileDialog.DefaultExt = MyExpName;//默认扩展名
                MysaveFileDialog.AddExtension = true;//是否自动添加扩展名
                MysaveFileDialog.Filter = "*." + MyExpName + "|." + MyExpName;
                MysaveFileDialog.OverwritePrompt = true;//文件已存在是否提示覆盖
                MysaveFileDialog.FileName = fileName;
                //dialogOpenFile.FileName = "文件名";//默认文件名
                MysaveFileDialog.CheckPathExists = true;//提示输入的文件名无效
                MysaveFileDialog.Title = "对话框标题";
                //显示对话框
                bool? b = MysaveFileDialog.ShowDialog();
                if (b == true)//点击保存
                {
                    fileName = MysaveFileDialog.FileName;
                    txt_DC.Text = fileName;
                    //恢复系统路径-涉及不到的可以去掉
                    Environment.CurrentDirectory = strPath;
                }
                else
                {
                    //恢复系统路径-涉及不到的可以去掉
                    Environment.CurrentDirectory = strPath;
                    return;
                }
                
    
                List<string> Datas = new List<string>();
                try
                {
                    if (true)//(File.Exists(fileName))
                    {
                        string sSQL = MakeSQL();
                        List<string> ERR = new List<string>();
                        int iRe = MyXSGLService.BFBHDDSQLQuery_txt(sSQL, ref Datas, ref ERR);
                        if (iRe != 0)
                        {
                            PubData.bflibShowError(Application.Current.MainWindow, ERR);
                            return;
                        }
                        else
                        {
                            
                            Stream stream = MysaveFileDialog.OpenFile();
                            while (MyXSGLService.GetString())
                            {
                                Byte[] fileContent = System.Text.Encoding.GetEncoding("gb2312").GetBytes(MyXSGLService.GetStringBuilder());
                                stream.Write(fileContent, 0, fileContent.Length);
                            }
                            stream.Close();
                            
                            MessageBox.Show("导出完成!");
    
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                
            }
    
    
    
    
    
  • 相关阅读:
    es5中的类 继承 (原型链继承,寄生继承,组合继承)
    typeScript类型
    javaScript 不可思议问题
    javaScript 运算符(操作符)
    window.a 与 window[a]区别
    Event Loop事件循环
    生产环境vue-router模式为history导致页面404
    Axios请求添加token
    vue页面利用keep-alive实现页面快速缓存
    js原型链原理
  • 原文地址:https://www.cnblogs.com/yuanzhongkui/p/4013048.html
Copyright © 2011-2022 走看看