国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

數(shù)據(jù)字典生成工具之旅(9):多線程使用及介紹

2019-11-17 02:28:58
字體:
供稿:網(wǎng)友

數(shù)據(jù)字典生成工具之旅(9):多線程使用及介紹

這一篇將在之前的代碼生成器上講解多線程的應(yīng)用,多線程的概念和好處這里就不多說了,另外從本篇開始后面的實例代碼都將放到淘寶的SVN管理工具上維護,大家可以直接使用SVN工具進行下載。好了下面進入本篇內(nèi)容。

閱讀目錄

  • 線程的應(yīng)用
  • winform程序中的多線程
  • 本章總結(jié)
  • 工具源代碼下載
  • 學(xué)習(xí)使用
回到頂部

線程的應(yīng)用

這里先講一下線程在Web程序中的一個應(yīng)用,之前的那一版代碼生成器沒有考慮表數(shù)量多的情形,這里先模擬一下在數(shù)據(jù)庫中創(chuàng)建300張表的情形,下面給出創(chuàng)建表的語句。

--模擬創(chuàng)建300張表,@IsDropTable=0 表示創(chuàng)建表 IsDropTable=1 表示刪除創(chuàng)建的模擬表DECLARE @IsDropTable AS BITDECLARE @total AS INT DECLARE @i AS INTSELECT @i=1,@total=300,@IsDropTable=0WHILE @i<=@totalBEGINDECLARE @strSQL AS VARCHAR(1000)    --創(chuàng)建表    SELECT @strSQL='        CREATE TABLE myTest'+CONVERT(VARCHAR,@i)+'        (            [UserGUID] [uniqueidentifier] NOT NULL        )        EXEC sp_addextendedPRoperty N''MS_DescrView Code

我們來看下執(zhí)行時間,差不多用了22秒,時間還是挺長的。可以將代碼改造一下,使用多線程來生成代碼。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;using System.Configuration;using System.Collections;using System.IO;using System.Data;using System.Threading;namespace Mysoft.Code.Services{    /// <summary>    /// 代碼生成類    /// </summary>    public class CodeGenerator    {        //模版文件路徑        private static string tmpPath = HttpContext.Current.Server.MapPath("/實體模版/Entity.vm");        //模版輸出路徑        private static string outPutPath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["outputPath"]);        private static readonly int Number10 = 400;        private static readonly int MaxThreadCount = 4;        /// <summary>        /// 批量生成代碼        /// </summary>        /// <param name="args">模版文件參數(shù)</param>        public static void BatchGenerator(List<Hashtable> args)        {            if (!Directory.Exists(outPutPath))            {                Directory.CreateDirectory(outPutPath);            }            //生成文件數(shù)量<Number10,則不開啟線程生成            if (args.Count < Number10)            {                DoWork(args);            }            else            {                //計算需要的線程數(shù)                int threadCount = args.Count % Number10 == 0 ? args.Count / Number10 : args.Count / Number10 + 1;                if (threadCount > MaxThreadCount)                {                    threadCount = MaxThreadCount;                }                //每個線程需要生成的實體數(shù)量                int threadPqgeSize = (args.Count / threadCount) + 1;                int total = 0;                //為每個線程準備參數(shù)                List<List<Hashtable>> threadParams = new List<List<Hashtable>>();                for (int i = 0; i < threadCount; i++)                {                    threadParams.Add(args.Skip(total).Take(threadPqgeSize).ToList());                    total += threadParams[i].Count;                }                //創(chuàng)建線程                List<Thread> threads = new List<Thread>();                for (int i = 1; i < threadCount; i++)                {                    Thread thread = new Thread(DoWork);                    thread.IsBackground = true;                    thread.Name = "CodeGenerator #" + i.ToString();                    threads.Add(thread);                    thread.Start(threadParams[i]);                }                // 為當前線程指派生成任務(wù)。                DoWork(threadParams[0]);                // 等待所有的編譯線程執(zhí)行線束。                foreach (Thread thread in threads)                {                    thread.Join();                }            }        }        private static void DoWork(Object listArgs)        {            List<Hashtable> list = (List<Hashtable>)listArgs;            foreach (Hashtable ht in list)            {                FileGen.GetFile(tmpPath, ht, string.Format("{0}//{1}.cs", outPutPath, ((DataTable)ht["T"]).Rows[0]["table_name"].ToString()));            }        }    }}
View Code

代碼思路,判斷要生成的實體數(shù)量和Number10的關(guān)系,然后計算所需的線程數(shù)。

關(guān)鍵的一點是thread.Join(),這段是主線程等待每個線程執(zhí)行完成。現(xiàn)在再來看下執(zhí)行時間,差不多用了13秒,節(jié)省了將近10S的時間。

回到頂部

winform程序中的多線程

下面來考慮這樣的一個場景,在生成了文件的時候馬上在列表中提示實體生成完成,即進度提示的功能。我們來看下winform中的兩種實現(xiàn)方式。

1.利用委托實現(xiàn)

先看一下普通線程實現(xiàn)方式,執(zhí)行的時候會拋出如下異常。

   foreach (var key in query)            {                dv.RowFilter = "tableid=" + key.tableid;                DataTable dtTable = dv.ToTable();                Hashtable ht = new Hashtable();                ht["T"] = dtTable;                string tableName = dtTable.Rows[0]["table_name"].ToString();                FileGen.GetFile(tmpPath, ht, string.Format("{0}//{1}.cs", outPutPath, tableName));                Thread thread = new Thread(BindMessage);                thread.IsBackground = true;                thread.Name = "BindMessage:" + key.tableid;                thread.Start(tableName);            }
View Code

先看一下msdn的介紹:

訪問 Windows 窗體控件本質(zhì)上不是線程安全的。如果有兩個或多個線程操作某一控件的狀態(tài),則可能會迫使該控件進入一種不一致的狀態(tài)。還可能出現(xiàn)其他與線程相關(guān)的 bug,包括爭用情況和死鎖。確保以線程安全方式訪問控件非常重要。

  C#中禁止跨線程直接訪問控件,InvokeRequired是為了解決這個問題而產(chǎn)生的,當一個控件的InvokeRequired屬性值為真時,說明有一個創(chuàng)建它以外的線程想訪問它。

于是改變了思路,新建線程用以執(zhí)行耗時的生成代碼操作,在每生成一個實體時,通知UI線程更新dataGridView,達到實時更新的效果,這樣主線程也不會阻塞了。

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using Mysoft.Map.Extensions.DAL;using System.Collections;using Mysoft.Code.Services;using System.IO;using System.Threading;namespace ThreadWin{    public partial class MainForm : Form    {        //模版文件路徑        private static string tmpPath = AppDomain.CurrentDomain.BaseDirectory + @"實體模版/Entity.vm";        //模版輸出路徑        private static st
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 宝兴县| 柳河县| 兴隆县| 西吉县| 永昌县| 安溪县| 兴海县| 虹口区| 淅川县| 合肥市| 三明市| 台州市| 梅河口市| 天津市| 三台县| 诸暨市| 北海市| 大厂| 海门市| 渭源县| 桑植县| 荣成市| 济源市| 荔浦县| 龙里县| 方山县| 平顺县| 彩票| 会东县| 牟定县| 台北市| 从江县| 上蔡县| 任丘市| 开阳县| 苏尼特右旗| 崇明县| 湾仔区| 瑞丽市| 登封市| 闽侯县|