Fork me on GitHub
多线程学习之限制同时运行的线程数量

多线程学习之限制同时运行的线程数量

最近闲暇之余,来搞搞,多线程学习,只为下个项目做准备,随着项目优化,开发,性能的考虑,慢慢要用到些以前不用的东西,先开始熟悉熟悉

先把东西放上来,欢迎大家赐教,比较好久木玩这东西了,肯定不完善,希望大家提出宝贵意见啊(嘿嘿~~)

 

大概功能描述:为了提高数据处理速度,把任务队列分别交给不同子线程去完成,同时对启动的新线程数量限制,避免线程数量过多照成机器卡壳

 

复制代码
 1 using System;
 2 using System.Threading;
 3 namespace ThreadTest
 4 {
 5   class ThreadMaxNum
 6     {
 7         static int NowThCount = 0;//当前已启动线程数量
 8         static int MaxThCount = 5;//允许最大启动线程数量
 9         static int RunNum = 15;//当前有多少个要处理的程序[任务队列]
10         public static void Run()
11         {
12             Thread NewTh;
13             while (true)
14             {
15                 //当前没有活动线程,且 任务队列 为空 说明任务完成了
16                 if (NowThCount == 0 && RunNum == 0)
17                     break;
18                 
19                 //任务队列为空 ,但是又线程运行中,就让主线程休息 下,在判断
20                 if (RunNum == 0 && NowThCount != 0) 
21                 {
22                     Thread.Sleep(2000);//休息
23                     continue;//再次判断
24                 }
25 
26                 //如果 当前活动线程数量 达到最大线程 就不在 开始新的任务
27                 if (NowThCount >= MaxThCount)
28                 {
29                     Thread.Sleep(2000);//休息
30                     continue;//再次判断
31                 }
32 
33                 //有 队列>0,且没有达到最大
34                 if (RunNum > 0 && NowThCount < MaxThCount)
35                 {
36                     //一个任务已经去执行了,应该减掉个,执行结果如何,这里不判断
37                     RunNum--;
38 
39                     NewTh = new Thread(new ThreadStart(RunNewFun));
40                     NewTh.Start();
41                 }
42             }
43             Console.WriteLine("任务队列,执行完成:"+RunNum);
44         }
45         static void RunNewFun()
46         {
47             NowThCount++;//加个
48 
49             Console.WriteLine("我是线程:" + Thread.CurrentThread.ManagedThreadId);
50             Thread.Sleep(3000);
51             Console.WriteLine("我是线程:" + Thread.CurrentThread.ManagedThreadId + ".....结束");
52 
53             NowThCount--;//减去
54         }
55     }
56 }
复制代码

 

 

NPOI导出Excel和基于office导出Excel表比较

首先介绍一下NPOI吧。

NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。
使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作。
 
NPOI的优势:
(一)传统操作Excel遇到的问题:
1、如果是.NET,需要在服务器端装Office,且及时更新它,以防漏洞,还需要设定权限允许.NET访问COM+,如果在导出过程中出问题可能导致服务器宕机。
2、Excel会把只包含数字的列进行类型转换,本来是文本型的,Excel会将其转成数值型的,比如编号000123会变成123。
3、导出时,如果字段内容以“-”或“=”开头,Excel会把它当成公式进行,会报错。
4、Excel会根据Excel文件前8行分析数据类型,如果正好你前8行某一列只是数字,那它会认为该列为数值型,自动将该列转变成类似1.42702E+17格式,日期列变成包含日期和数字的。
(二)使用NPOI的优势
1、你不需要在服务器上安装微软的Office,可以避免版权问题。
2、使用起来比Office PIAAPI更加方便,更人性化。
3、你不用去花大力气维护NPOINPOI Team会不断更新、改善NPOI,绝对省成本。
 
基于office导出到Excel实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public static void ExportExcel(string fileName, DataGridView myDGV,bool isShowDialog)
      {
          string saveFileName = "";
          if (isShowDialog)
          {
              //bool fileSaved = false;
              SaveFileDialog saveDialog = new SaveFileDialog();
              saveDialog.DefaultExt = "xls";
              saveDialog.Filter = "Excel文件|*.xls";
              saveDialog.FileName = fileName;
              saveDialog.ShowDialog();
              saveFileName = saveDialog.FileName;
              if (saveFileName.IndexOf(":") < 0) return; //被点了取消
          }
          else
          {
             // saveFileName = Application.StartupPath + @"\导出记录\" + fileName + ".xls";
              saveFileName = fileName;
          }
          Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
          if (xlApp == null)
          {
              MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel");
              return;
          }
 
          Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
          Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
          Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1
 
          //写入标题
          for (int i = 0; i < myDGV.ColumnCount; i++)
          {
              worksheet.Cells[1, i + 1] = myDGV.Columns[i].HeaderText;
          }
          //写入数值
          for (int r = 0; r < myDGV.Rows.Count; r++)
          {
              for (int i = 0; i < myDGV.ColumnCount; i++)
              {
                  if (myDGV[i, r].ValueType == typeof(string)
                     || myDGV[i, r].ValueType == typeof(DateTime))//这里就是验证DataGridView单元格中的类型,如果是string或是DataTime类型,则在放入缓 存时在该内容前加入" ";
                  {
                      worksheet.Cells[r + 2, i + 1] = "'" + myDGV.Rows[r].Cells[i].Value;
                  }
                  else
                  {
                      worksheet.Cells[r + 2, i + 1] = myDGV.Rows[r].Cells[i].Value;
                  }
              }
              System.Windows.Forms.Application.DoEvents();
          }
          worksheet.Columns.EntireColumn.AutoFit();//列宽自适应
          //if (Microsoft.Office.Interop.cmbxType.Text != "Notification")
          //{
          //    Excel.Range rg = worksheet.get_Range(worksheet.Cells[2, 2], worksheet.Cells[ds.Tables[0].Rows.Count + 1, 2]);
          //    rg.NumberFormat = "00000000";
          //}
 
          if (saveFileName != "")
          {
              try
              {
                  workbook.Saved = true;
                  workbook.SaveCopyAs(saveFileName);
                  //fileSaved = true;
              }
              catch (Exception ex)
              {
                  //fileSaved = false;
                  MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
              }
 
          }
          //else
          //{
          //    fileSaved = false;
          //}
          xlApp.Quit();
          GC.Collect();//强行销毁
          // if (fileSaved && System.IO.File.Exists(saveFileName)) System.Diagnostics.Process.Start(saveFileName); //打开EXCEL
          MessageBox.Show(fileName + "保存成功", "提示", MessageBoxButtons.OK);
      }

 NPOI导出到Excel表实现:

/// <summary>
        /// NPOI导出Excel,不依赖本地是否装有Excel,导出速度快
        /// </summary>
        /// <param name="dataGridView1">要导出的dataGridView控件</param>
        /// <param name="sheetName">sheet表名</param>
        public static void ExportToExcel(DataGridView dataGridView1, string sheetName)
        {
            SaveFileDialog fileDialog = new SaveFileDialog();
            fileDialog.Filter = "Excel|*.xls";
            if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
            {
                return;
            }
            //不允许dataGridView显示添加行,负责导出时会报最后一行未实例化错误
            dataGridView1.AllowUserToAddRows = false;
            HSSFWorkbook workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet(sheetName);
            IRow rowHead = sheet.CreateRow(0);
 
            //填写表头
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
            {
                rowHead.CreateCell(i, CellType.STRING).SetCellValue(dataGridView1.Columns[i].HeaderText.ToString());
            }
            //填写内容
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                IRow row = sheet.CreateRow(i + 1);
                for (int j = 0; j < dataGridView1.Columns.Count; j++)
                {
                    row.CreateCell(j, CellType.STRING).SetCellValue(dataGridView1.Rows[i].Cells[j].Value.ToString());
                }
            }         
 
            using (FileStream stream = File.OpenWrite(fileDialog.FileName))
            {
                workbook.Write(stream);
                stream.Close();
            }
            MessageBox.Show("导出数据成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            GC.Collect();
        }

  经过比较:如果导出50000条int类型的数据,基于office导出需要10分钟左右的时间,NPOI导出则需要3秒钟左右的时间。

  NPOI导出时间截图如下:

基于office导出时间截图如下:

呵呵,看出来两者的速度了吧,并且NPOI用起来相当的灵活,第一次写博客,希望和大家共同分享,共同学习,共同进步!

posted on 2013-05-14 17:36  HackerVirus  阅读(568)  评论(0编辑  收藏  举报