EDM开发过程中遇到的其他问题
1、session:
session记录到数据库中,sql数据库自带程序C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe,可以在命令行执行
“C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe -S . -E -ssadd -sstype c -d TestSessionStore”会在数据库中生成一个名为TestSessionStore的数据库,这就是为session而生的,然后在web.config中的sessionState改为
这样,再用sessin就会记录在数据库中了。不过如果直接运行.exe程序手动生成数据库,会报错,提示无会话状态。
2、task:
用多线程方法可以减少发送大量邮件花费时间长的问题(SMTP限制之后再说),task是对ThreadPool线程池的封装,相对于线程池具有很多优势,比如:(1)ThreadPool不支持线程的取消、完成、失败通知等交互性操作;(2)ThreadPool不支持线程执行的先后次序;通过对ThreadPool进行封装,于是.net Framework4.0有了TPL和Task。也就是说,相对于线程池,task使我能对线程的可控性大大提高了。
(1)普通用法:
Task t = new Task(() => { Console.WriteLine("任务开始"); }); t.Start(); t.ContinueWith((task) => { Console.WriteLine("任务完成"); });
(2)任物工厂:
Task[] tasks = new Task[] { taskFactory.StartNew(() => Add(cts.Token)), taskFactory.StartNew(() => Add(cts.Token)), taskFactory.StartNew(() => Add(cts.Token)) }; //CancellationToken.None指示TasksEnded不能被取消 taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None);
CancellationTokenSource是通知 ,告知其应被取消。当其被实例化后,执行.Canale()方法,即可取消线程。
task可以等待某个线程执行完成后再执行:
t1.Wait(); //等待任务t1完成Task.WaitAll(t2, t3); //等待任务t2和t3完成t4.ContinueWith(TaskEndedByCatch); //t4执行完成后继续执行TaskEndedByCatch方法taskFactory.ContinueWhenAll(tasks, TasksEnded, CancellationToken.None); //工厂内所有线程执行完毕后,执行TasksEnded方法,CancellationToken.None指示此方法不能被取消。
3、解压:
对于传入的文件,可能是文本文件,也可能是压缩文件,这就要求将传入的压缩文件解压并对文件路径进行记录,而且由于压缩文件格式不确定,所以调用WinRAR软件进行解压。
1 ///2 /// 利用 WinRAR 进行解压缩 3 /// 4 /// 文件解压路径(绝对路径) 5 /// 将要解压缩文件的存放目录(绝对路径) 6 /// 将要解压缩文件名(包括后缀) 7 ///true 或 false。解压缩成功返回 true,反之,false。 8 public bool UnRarOrZip(string path, string rarPath, string rarName) 9 {10 bool flag = false;11 try12 {13 RegistryKey regkey = Registry.ClassesRoot.OpenSubKey(@"WinRAR.ZIP\shell\open\command");//根据注册表,获取WinRAR的运行路径14 if (regkey != null)15 {16 Object regvalue = regkey.GetValue("");17 string rarexe = regvalue.ToString();18 regkey.Close();19 rarexe = rarexe.Substring(1, rarexe.Length - 7);20 21 Directory.CreateDirectory(path);22 //解压缩命令,相当于在要压缩文件(rarName)上点右键->WinRAR->解压到当前文件夹23 string cmd = string.Format("x {0} {1} -y",24 rarName,25 path);26 var startinfo = new ProcessStartInfo27 {28 FileName = rarexe,29 Arguments = cmd,30 WindowStyle = ProcessWindowStyle.Hidden,31 WorkingDirectory = rarPath32 };33 34 var process = new Process {StartInfo = startinfo};35 process.Start();36 process.WaitForExit();37 if (process.HasExited)38 {39 flag = true;40 }41 process.Close();42 }43 }44 catch (Exception e)45 {46 throw e;47 }48 return flag;49 }50 51 public void Dispose()52 {53 throw new NotImplementedException();54 }55 }
4、文件操作:
系统中需要对文件和文件夹进行读写操作。
创建文件或文件夹:
1 //创建文件夹 2 public void CreateDirectory(string pathName) 3 { 4 if (!Directory.Exists(pathName)) 5 { 6 Directory.CreateDirectory(pathName); 7 } 8 } 9 10 //创建文件11 public void CreateFile(string pathName)12 {13 if (!File.Exists(pathName))14 {15 File.Create(pathName);16 }17 }
获取文件名或文件夹名:
1 //获取目录下所有文件名 2 public ListGetAllFiles(string path) 3 { 4 var dir = new DirectoryInfo(path); 5 var fiList = new List (); 6 if (dir.Exists) 7 { 8 fiList.AddRange(dir.GetFiles()); 9 }10 var fileName = new List ();11 if (fiList.Count != 0)12 {13 fileName.AddRange(fiList.Select(dl => dl.Name));14 }15 return fileName;16 }17 18 //获取目录下所有文件夹名19 public List GetAllDirectorys(string path)20 {21 var dir = new DirectoryInfo(path);22 var diList = new List ();23 if (dir.Exists)24 {25 diList.AddRange(dir.GetDirectories());26 }27 var fileName = new List ();28 if (diList.Count != 0)29 {30 fileName.AddRange(diList.Select(dl => dl.Name));31 }32 return fileName;33 }
删除文件:
1 //删除文件2 public void DeleteFile(string path)3 {4 //判断文件是不是存在5 if (!File.Exists(path)) return;6 //文件删除7 File.Delete(path);8 }
清空文件夹:
1 //清空文件夹 2 public void DeleteDirectory(string path) 3 { 4 //判断文件是不是存在 5 if (!Directory.Exists(path)) return; 6 //文件夹清空 7 DeleteFolder(path); 8 } 9 public static void DeleteFolder(string dir)10 {11 foreach (string d in Directory.GetFileSystemEntries(dir))12 {13 if (File.Exists(d))14 {15 FileInfo fi = new FileInfo(d);16 if (fi.Attributes.ToString().IndexOf("ReadOnly", System.StringComparison.Ordinal) != -1)17 fi.Attributes = FileAttributes.Normal;18 File.Delete(d);//直接删除其中的文件 19 }20 else21 {22 var d1 = new DirectoryInfo(d);23 if (d1.GetFiles().Length != 0)24 {25 DeleteFolder(d1.FullName);////递归删除子文件夹26 }27 Directory.Delete(d);28 }29 }30 }
获取目录下第一次出现文件的路径:
1 public string GetNewUrl(string pathUrl, string pathName) 2 { 3 var files = GetAllFiles(pathUrl); 4 if (files.Count == 0) 5 { 6 var directions = GetAllDirectorys(pathUrl); 7 if (directions.Count > 0) 8 { 9 pathName += "/" + directions.FirstOrDefault();10 GetNewUrl(pathUrl + "\\" + directions.FirstOrDefault(), pathName);11 }12 }13 return pathName;14 }
5、对于excel文件的导入导出操作:
系统数据导入可能是txt文件,也可能是excel文件。对于导入的Excel文件,使用NPOI进行操作。
excel文件操作类:
1 private HSSFWorkbook _hssfworkbook; 2 3 public void InitializeWorkbook(string path) 4 { 5 using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) 6 { 7 _hssfworkbook = new HSSFWorkbook(file); 8 } 9 }10 11 public void InitializeWorkbook(FileUpload uploadfile)12 {13 uploadfile.SaveAs(HttpContext.Current.Server.MapPath("~/Content/excel.xls"));14 string path = HttpContext.Current.Server.MapPath("~/Content/excel.xls");15 using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))16 {17 _hssfworkbook = new HSSFWorkbook(file);18 }19 }20 21 ///22 /// 数据导出23 /// 24 /// Excel Sheet名称25 /// 列名26 /// 设置列值的委托方法27 ///28 public MemoryStream ExportEdm(string sheetName, string[] cellNames, Action setCellValue)29 {30 using (var output = new MemoryStream())31 {32 IWorkbook workBook = new HSSFWorkbook();33 var sheet = workBook.CreateSheet(sheetName);34 var headRow = sheet.CreateRow(0);35 for (int i = 0; i < cellNames.Length; i++)36 headRow.CreateCell(i).SetCellValue(cellNames[i]);37 setCellValue(sheet);38 for (int i = 0; i < cellNames.Length; i++)39 sheet.AutoSizeColumn(i);40 workBook.Write(output);41 return output;42 }43 }
excel导入导出实例:
1 ///2 /// Excel数据导入 3 /// 4 public void GetExcel(string path) 5 { 6 var uplodeExcel = new ExcelHelper(); 7 uplodeExcel.InitializeWorkbook(path); 8 var list = uplodeExcel.SetCurrentSheet(); 9 }10 11 ///12 /// Excel导出EDM13 /// 14 public ActionResult ReportExcel()15 {16 var list = (from entity in models17 let model = _sendService.GetCountList(entity.SendTableName)18 select new SendTypeStatis19 {}).ToList();20 string[] cellNames =21 {22 "EDM名称", "真实路径"23 };24 var output = new ReportExcel().ExportEdm("EDM导出", cellNames, r =>25 {26 if (!list.Any()) return;27 var rowNumber = 1;28 foreach (var ml in list)29 {30 var number = 0;31 var row = r.CreateRow(rowNumber++);32 row.CreateCell(number++).SetCellValue(ml.EdmName);33 row.CreateCell(number).SetCellValue(ml.EdmNewUrl);34 }35 });36 string saveAs = string.Format("数据导出-{0:d}.xls", DateTime.Now.Ticks);37 Response.ContentType = "application/vnd.ms-excel";38 Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", saveAs));39 Response.BinaryWrite(output.GetBuffer());40 Response.End();41 42 return Json("success");43 }