顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

2011年10月18日 星期二

[Oracle] 測試OracleConnection是否正確關閉

  • 若Connection String沒有設定Pooling,預設是開啟(true)。

  • 查詢V$Session檢視connection建立情況:OracleConnection.Open()後會建立一connection, 查詢V$Session會出現一筆資料(需以SYSDBA身份登入)
    SELECT SID, USER#, Serial#, audsid, STATUS,
            SchemaName, OsUser, Process, Machine, Program
    FROM V$Session
    WHERE OsUser='Auser'


  • 關閉connection, 除了OracleConnection.Close()外, 也需要OracleDataReader.Close()(如果有reader的話), 否則connection無法返還至pool.
    以下例子中, 執行reader.Close()後, V$Session不再有connection的資料,
    若reader.Close()未執行, V$Session會有此connection的資料存在.
        public static void RunSample()
        {
            using (OracleConnection conn =
                new OracleConnection(
                "Data Source=dbserver;User ID=auser;Password=auser;Max Pool Size=3"))
            {
                conn.Open();

                using (OracleCommand comm =
                    new OracleCommand(Settings.GetHostsCmd, conn))
                {
                    OracleDataReader reader = comm.ExecuteReader();
                    while (reader.Read())
                    {
                        Console.WriteLine(string.Format("{0} {1} {2}",
                            reader.GetValue(0),
                            reader.GetValue(1),
                            reader.GetValue(2)));
                    }

                    //reader.Close();
                    Console.WriteLine("Done! ");
                }
            }// 離開using scope, Connection會被close.

            // 移除pool內全部的connection.
            // 若只close connection 沒有close reader,
            // connection沒有返還至pool, 因此無法移除此connection. 
            // 在V$Session可以查詢到此connection.
            OracleConnection.ClearAllPools();
        }

2011年7月7日 星期四

C# 將圖檔/Imaget轉換為byte array

以下是2種方式的測試結果,
一是使用FileStream讀入圖檔,
另一是使用System.Drawing.Image讀入圖檔。
           
        // 先將圖檔讀到FileStream, 再轉換為byte array。
        private static void ToBinaryByFileStream(string imageFile)
        {
            FileStream fs = new FileStream(imageFile, FileMode.Open);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
        }

        // 先將圖檔讀到Image object, 再轉換為byte array。
        private static void ToBinaryByImageObj(string imageFile)
        {
            System.Drawing.Image image = System.Drawing.Image.FromFile(imageFile);
            MemoryStream mr = new MemoryStream();
            image.Save(mr, System.Drawing.Imaging.ImageFormat.Png);
            byte[] binaryImage = mr.ToArray();
            mr.Dispose();
            image.Dispose();
        }

// 測試method。 
public static void ConvertImageToBinary()
        {
            Console.WriteLine("=== Convert the image file to the binary object. ===");

            string imageFolder = @"D:\Images";
            // 測試的image數量。
            int sampleCount = 100;

            string[] imagePaths = Directory.GetFiles(imageFolder, "*.png");
            if (0 == imagePaths.Length)
            {
                Console.WriteLine("No image found.");
                return;
            }

            Stopwatch sw = new Stopwatch();

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByFileStream(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By FileStream: {0} ms.",
                sw.ElapsedMilliseconds);

            sw.Reset();
            sw.Start();
            for (int i = 0; i < sampleCount; i++)
            {
                ToBinaryByImageObj(imagePaths[i]);
            }
            sw.Stop();
            Console.WriteLine("By System.Drawing.Image: {0} ms.",
                sw.ElapsedMilliseconds);
        }


測試100張圖檔的結果

Unit: ms

By FileStream
152
By System.Drawing.Image
2692


Image object會讀取圖檔的相關資訊,
相對地,FileStream只作資料的搬移,所以效能上會快很多。

2011年7月4日 星期一

.Net 語音應用程式

在Win7環境下開發語音應用程式:SAPI 已包含在win7內,不用另外安裝。
執行畫面:


加入Reference:
System.Speech.Synthesis:文字語音轉換器
Microsoft.VisualBasic:繁簡體轉換


    public partial class Form1 : Form
    {
        SpeechSynthesizer m_Speaker; // 文字語音轉換器。 
        public Form1()
        {
            InitializeComponent();
            m_Speaker = new SpeechSynthesizer();
        }

        // 朗讀英文句子。
        private void buttonReadEng_Click(object sender, EventArgs e)
        {
            // 設定語音為英文。
            m_Speaker.SelectVoice("Microsoft Anna"); 
            m_Speaker.SpeakAsync(this.buttonReadEng.Text);
        }

        // 朗讀中文句子。
        private void buttonReadCht_Click(object sender, EventArgs e)
        {
            // 中文語音部分,系統預設為簡體中文。
            m_Speaker.SelectVoice("Microsoft Simplified Chinese");
            // 將原本繁體文字轉為簡體,SpeechSynthesizer才能辨識。
            // 輸入文字(繁體),轉換類型,區域設定ID(zh-cn)。
            string simCht = Strings.StrConv(
                buttonReadCht.Text, VbStrConv.SimplifiedChinese, 2052); 
            m_Speaker.SpeakAsync(simCht);
        }
    }


參考:
SAPI介紹:http://www.cnblogs.com/TravelingLight/archive/2010/12/09/1901300.html
在XP的環境下:http://www.chncms.com/2010/12/2/DOTNETVOICESPEACH.html
Local ID:http://msdn.microsoft.com/en-us/library/0h88fahh.aspx

2011年5月16日 星期一

C# 辨斷Form/UserControl在Design mode?

使用VS時, 在Designer查看Form, 或將UserControl拉進designer,
會因為一些初始操作而產生exception, 像使用外部資源(資料庫連線)等,
這些操作其實在design模式並不需要,
那要如何辨斷Form/UserControl是在Design模式下, 進而忽略這些操作呢?

可以使用Form/UserControl的屬性, DesignMode.
DesignMode在使用上有限制, 它在constructor內無效(always return false),
於是我們將一些design模式下不需要的操作移到load handler裡,
當它是design模式就直接return, 忽略掉這些操作:


        public Form1()
        {
            InitializeComponent();

            // Load handler
            this.Load += new EventHandler(Form1_Load);
        }

        void Form1_Load(object sender, EventArgs e)
        {
           
            if (this.DesignMode) // 如果是design模式, 直接return.
                return;
           
            // Design模式下不需要的操作, eg: 資料庫連線
        }