1. BotCheck 改版...

    有鑑於好奇心強的網友,回應時老愛研究 BotCheck 跟內容的關聯性... (Honga 就是你...),一時興起把 BotCheck 的 ASCX 改寫了一下,會在驗証通過時,把 BotCheck 的題目及答案附加在 comment 的後面,就像這樣:

    image

    免的每次都在那邊貼這次的 BotCheck 是啥.. 哈! 特此留念!

    2008/04/01 .NET ASP.NET 作品集 有的沒的

  2. Code Formatter 更新: 複製CODE及HTML預覽

    無聊的宅男沒事又改起這個Live Writer的外掛程式了。原本的版本還不錯用,不過就是覺的少了點什麼... 除了加個框之外,跟網站版本也沒什麼差別嘛。用了一陣子,又加了兩個小功能上去...

     

    COPY CODE

    這個功能是從MSDN學來的,MSDN文章的範例程式碼,都會附個鈕讓讀者按,按一下程式碼就會被覆製到簡貼簿... 這個功能還蠻實用的,因為我常常這樣貼... 哈哈,不曉得看我 BLOG 的人有沒有這習慣? 不管了,我的BLOG,我寫的PLUGINS,我說好用的東西當然要加上去... 底下是改版後的外掛程式,張貼程式碼的樣子:

    ----------------[以下開始]------------------

    測試用的 C# Code Sample..[copy code]
            //        // 不重要的程式碼... 拿來當 Model 用的...        //        private int CountLeadingSpaces(string line)        {            int count = 0;            foreach (char ch in line)            {                if (ch == ' ')                {                    count++;                }                else                {                    break;                }            }            return count;        }
    
       1:  //
    
       2:  // 不重要的程式碼... 拿來當 Model 用的...
    
       3:  //
    
       4:  private int CountLeadingSpaces(string line)
    
       5:  {
    
       6:      int count = 0;
    
       7:      foreach (char ch in line)
    
       8:      {
    
       9:          if (ch == ' ')
    
      10:          {
    
      11:              count++;
    
      12:          }
    
      13:          else
    
      14:          {
    
      15:              break;
    
      16:          }
    
      17:      }
    
      18:      return count;
    
      19:  }
    

    ----------------[結束]-----------------------

     

     

    HTML PREVIEW

    另一個無聊的功能,是過去在寫些HTML相關的文章,常常要做這樣的動作: 一方面要想辦法把HTML秀到網頁上,就得用這種外掛來處理,不過另一方面又要讓讀者直接看一下HTML顯示出來的效果,一樣的CODE又要切到HTML編輯模式貼一次... 這次就是要省掉這個懶人工夫... 一次到位。來試一下這個功能:

    ----------------[以下開始]------------------

    HTML測試[copy code]
    <H3>這是H3的效果</H3><H3>這是H3的效果</H3><H3>這是H3的效果</H3><H3>這是H3的效果</H3><H3>這是H3的效果</H3>
    
       1:  <H3>這是H3的效果</H3>
    
       2:  <H3>這是H3的效果</H3>
    
       3:  <H3>這是H3的效果</H3>
    
       4:  <H3>這是H3的效果</H3>
    
       5:  <H3>這是H3的效果</H3>
    


    HTML Preview

    這是H3的效果

    這是H3的效果

    這是H3的效果

    這是H3的效果

    這是H3的效果

    ----------------[結束]-----------------------

     

    好,展示完畢,沒什麼突破的進展,純粹自己好用而以[H]。我也不曉得有沒有人在用,懶的打包放網站了,需要的人再跟我要...

    2008/03/31 .NET HTML/CSS 作品集 有的沒的

  3. WLW Plugins: Code Formatter

    最近常常貼一些需要附上程式碼的文章, 我都借助 [c# code format] 這網站幫忙轉, 轉成好看一點的 HTML code.. 然後 Live Writer 切到原始碼的模式去改 HTML, 然後再切回來際續編...

    人果然是懶惰的動物, 之前久久寫一篇還好, 最近就開始不耐煩了... 試了一套 Syntax Highlight 的 WLW plugins, 畫面不錯, 不過中文會亂掉.. 想說 c# code format 這網站的主人有 share source code, 我就把它拿來包成 Windows Live Writer Plugins 好了...

    就是這念頭開始寫這個 project, 蠻好寫的, 兩三個小時過去就堪用了, 經過幾天試用慢慢改成現在的樣子, 先現寶一下, 放幾張圖:

     

    [圖 1] 編輯畫面
    image

     

    [圖 2] 預覽畫面 (底下當然要加點廣告... )
    image

     

    結果就不用貼圖了, 底下這段就是用這 plugins 貼進來的...

     

    [程式 1] 這是測試程式

       1:  using System;
    
       2:  using System.IO;
    
       3:  using System.Threading;
    
       4:   
    
       5:  public class Program {
    
       6:    public static void Main(string[] args) {
    
       7:      Console.WriteLine("Hello!!" );
    
       8:    }
    
       9:  }
    

     

    看起來效果還不錯, 雖然跟之前差不多, 不過手工的部份少很多, 貼上, 按 OK, 就收工了! 這個 c# code format 提供的 library 還不賴, 效果也是我試用幾種 lib 後比較滿意的, 滿意的地方是:

    1. Pure C# 開發的, 程式很短, 不過看的出作者功力不錯, 架構啥都棒.
    2. 用習慣了, 之前都用它網站版本的. 很熟悉它轉出來的格式.
    3. 轉出來的 code 比較乾淨. 不過它需要另外搭配它的 CSS.
    4. Unicode, 沒有什麼中文亂碼的問題.

    當初最主要用它的原因就是 (3), 其它捨棄 CSS 的結果, 就是產生出來的 HTML 參著一大堆 color code, 老實說這種 HTML code 看起來就很痛苦. 我是不想看啦, 不過我必需切到 HTML view 去貼上這堆字啊...  c# code format 雖然要另外補上 .css, 不過看起來就清爽多了. 我直接把它附的 CSS 貼到我用的 community server 的 custom themes 裡 (部落格管理裡面就可以直接加, 不用改檔案), 用起來就很輕鬆愉快了 :D

    要來看 code 嗎? 其實 code 就沒什麼好看的了, 需要的直接抓回去看吧. 倒是不常寫 WinForm 的我, 竟然被內建的 ComboBox 小整了一下... WinForm 內建的 ComboBox 功能很完整, Items 可以放 object, 然後再指定 ValueMember, DisplayMember... blah blah. 當然也有直接提供最簡單的 Text Editor, 一行字就是一個 Item ...

    image

    不過, 我要的是很簡單的 Value / Display 分別指定就好, 就是這個 plugins 讓 user 選擇格式的地方 (如上圖), 我希望第一項的 Value 是 "HTML", 而顯示的是 "HTML / XML / ASP.NET", 這樣簡單的要求, 我心裡想... 這麼簡單, 一定可以直接用 Designer 填一填就搞定, 不用再去寫 code, 就可以 init 完成..

    沒想到找了半天還真的找不到! :@ 翻了 MSDN, Microsoft community 等等技術支援網站通通都沒有. 教的都是一堆我覺的拖褲子放屁的作法... 不過是五個固定的選單而以啊...

    到最後, 宣告放棄, 妥協了... 我這個功能最後是用這幾行 code 搞定的... ㄨ!!! 本來一行 code 都不想寫的...

     

    替 ComboBox 設定初始值的程式碼片段:
       1: comboBox1.DisplayMember = "Value";
    
       2: comboBox1.ValueMember = "Key";
    
       3: comboBox1.Items.Add(new KeyValuePair<string, string>("HTML",  "HTML / XML / ASP.NET"));
    
       4: comboBox1.Items.Add(new KeyValuePair<string, string>("CS",    "C#"));
    
       5: comboBox1.Items.Add(new KeyValuePair<string, string>("VB",    "Visual Basic.NET"));
    
       6: comboBox1.Items.Add(new KeyValuePair<string, string>("MSH",   "MSH (PowerShell)"));
    
       7: comboBox1.Items.Add(new KeyValuePair<string, string>("SQL",   "T-SQL"));
    
       8: comboBox1.SelectedIndex = 1;
    

     

    哈, 最後這邊收的不大漂亮, 不過不管了, 還好沒幾行. 這個 plugins 需要的就自己抓去用吧, 以後可能會不定時更新. 有啥改進意見可以留話給我, 不過嘛, 當然是有空 & 想改才有動力去開 visual studio .. [H]

     

    --
    下載: code formatter plugins

    2008/03/08 .NET 作品集

  4. Tips: 遠端桌面連線的小技巧

    查了文件, 才發現可以這樣用... 平常連到 server 用的遠端桌面連現, 常碰到幾個問題:

    1. 每次都要打 IP, 能不能拉捷逕出來, 我常連的那台只要點兩下就自動登入?
    2. 只有那幾種解析度可以選, 沒有我要的...
    3. 遠端桌面連進去的畫面, 跟本機的不一樣. 看不到某些在本機才看的到的訊息...

    原來這些都有解啊... (1) 最簡單, 把設定存檔就好, 就附圖的資訊, 底下有 [Save As], 以後直接點兩下存好的檔案就好了.

    image

     

    再來, (2) 跟 (3) 其實也有解, 只要先打開 DOS Prompt, 輸入  MSTSC /? 就會出現這個說明畫面:

    image

     

    答案就在影片中... 加上 /w:1440 /h:900 參數, 就可以用寬螢幕的解析度 1440 x 900 來搖控遠端的 server 了. 想要看 console (本機) 的畫面嘛? 比如有時 service 的 error message 只會秀在 console.. 這時只要加上 /console 參數就好. 整段指令如下:

    image

    開出來的視窗:

    image

    嗯, 看寬螢幕的果然比較爽, 當然這樣也就有機會用雙螢幕了. 小技巧, 需要的人可以參考看看!

    2008/03/06 Tips 技術隨筆

  5. Memory Management (III) - .NET CLR ?

    上篇 & 上上篇 ,同樣的問題,我改用 .NET 開發是不是就搞定了? 其實這篇才是我要寫的重點,只不過引言寫太高興,就是兩篇文章了,咳咳… 有人在問,為什麼我老是寫些冷門的文章? 沒辦法… 大家都在寫的東西我就沒興趣寫了,文筆沒別人好,網站沒別人漂亮,連範例程式都沒別人炫,只好挑些沒人寫的內容…

    大部份討論這主題的文章,講的都是 GC, GC 的 generation,IDisposable,還有 Heap 等等,不過這些知識都無法直接回答這次問題。底下的例子你會發現,預設的 GC 也無法解決 memory fragment 的問題,不過實際上是有解的,只是還要動用到秘技…

    回題,先來看看之前的問題為什麼會是個問題? 萬惡之首都在: 指標 (POINTER)。

    因為有 pointer,因此 C 絕對不能 自動 幫你調整記憶體位置,也就一定會有這種問題。看到為何我在上篇提到的程式碼要把 pointer 的值印出來? 因為這代表我可以輕易拿的到實際的位址,因此任何重新定址 (relocation) 的動作一定會影響到程式的執行。所以最根本的解決辦法就是把 pointer 這東西拿掉。

    年紀較輕的程式語言,如我常提到的 Java 跟 C#,都完完全全的把 pointer 從語言內移掉了,只留下 reference 這類差不多的東西。除了拿不到絕對的 address 之外,其它功能一個都不缺。但是這樣帶來的好處是很明顯的,除了一般書上講到爛的理由: “更安全,更簡易” 之外,很重要的一點就是,像 CLR or JavaVM 這種環境,開始有機會去搬移記憶體配置的區塊,徹底的由系統層面解決這種問題了。

    .NET / Java 回收記憶體的動作是自動的,就是常聽到的 Garbage Collection,而上面提到的 relocation,就是指在回收時順便把剩下已配置的空間排在一起,搬移記憶體區塊所需要的重新定址動作。這種類型的 GC 有個特別的名辭,叫作 compact collection。理論上,.NET 已經具備這樣的條件了,應該要有能力可以解決這樣的問題。

    不過 “可以解決” 跟 “已經解決” 仍然有一段差距,那麼現在的 .NET CLR 到底行不行? 一樣的範例程式用 C# 改寫一下,同樣的試看看,不過這次懶的再放好幾種版本試試看了,除了最大可用記憶體可能有差別之外,其它應該都統一了。我只針對 .NET 2.0 (x86) 一種版本測試,一樣,鐵齒的讀者們,有興趣就抓回去試一試…。

    整段程式碼跟之前 C 版本大同小異,就是照順序配置 64mb 的 byte[],直到丟出 OutOfMemoryException,然後跳著釋放,接著再配置 72mb 的 byte[],看看能不能配置成功? 直到再丟出 OutOfMemoryException 為止,能配置多少記憶體? 這邊為了方便,我直接在 vista x86 系統上測試:

    測試的結果令我想殺人,竟然是 FAIL ? 放掉的空間拿不回來…

    後來想到,程式移除 reference,不見得會立刻釋放記憶體,總得等垃圾車 (Garbage Collect) 來收拾一下… 手動呼叫了 GC,也強迫指定要回收所有的 Generation 了 (呼叫: GC.Collect(GC.MaxGeneraion) ) 再試一次:

    結果好不到那裡去,難到我沒用市政府的垃圾袋嘛? [:@] 查了一下 MSDN,常見的 generation 問題也試過,沒有用。90% 講 CLR GC 的問題都在探討 generation 的問題…  查到某 Java 名人的 文章,提到了 compact collection 比較接近,不過沒有講怎麼明確的啟動這樣的 GC 啊… 後來去翻 .NET runtime 裡關於 garbage collection 的設定,發現還有這玩意… gcConcurrent / gcServer:

    gcConcurrent: Specifies whether the common language runtime runs garbage collection on a separate thread.

    gcServer: Specifies whether the common language runtime runs server garbage collection.

    講的很清楚,不過對我沒啥用。gcConcurrent可能的影響是,也許呼叫後系統還在GC,我的程式就先跑下去了? 因此這東西關掉也許有幫助,再來試一次:

    真慘,一點幫助都沒有… 放掉的 768MB,只撈回 72MB,再來看一下最後一個 gcServer,看它的 HELP 看不大出來什麼是 “server garbage collection” ? 算了,試一下比較快:

    Bingo,看來這個參數下下去才是我預期的結果,放掉了 576MB,後面撈了 648MB 回來。這樣的作法,已經完全不會受到 memory fragment 問題的影響,証實了 compact collection 是有發恢它的效用的,只不過這個參數實際的作用,翻遍了 Google / MSDN,得到的都是很模菱兩可的答案,不外乎是你的程式如果是 blah blah blah 的話就要用 gcServer,這樣會比較好之類的,不過實際的差別則看不大出來。沒有任何一篇文件明確提到 server gc 會做 compact collection (如果這篇不算的話,哈哈),而 workstation gc 不會,也許前面的方式也會觸發 compact collection也說不定,只是時機不成熟…

    抱著不可能的希望,用 Reflector追看看,果然不出所料,Reflector也看不到細節,因為全都呼叫 native code 去了。不過這次的測試,至少確定了,在啟用 gcServer option 之後,CLR 的 GC 是會進行 compact collection 的。

    寫到這裡,本系列文章結束,只是為了在新的平台驗證古早的問題而以,果然時代在進步,以前耽心的問題現在都不再是問題了。這一連串試下來,學到了一課,原來 gcServer 有這個差別,算是值回票價了。最後把我的測試程式碼貼一下,一樣,歡迎拿去各種平台試一下,有不一樣的結果也記得通知我一聲!

    [Program.cs]

    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace ClrMemMgmt
    {
        class Program
        {
            static void Main(string[] args) {
                List<byte[]> buffer1 = new List<byte[]>();
                List<byte[]> buffer2 = new List<byte[]>();
                List<byte[]> buffer3 = new List<byte[]>();
                
                //            
                //    allocate             
                //            
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("1. Allocate 64mb block(s) as more as possible...");
                try
                {
                    while (true)
                    {
                        buffer1.Add(new byte[64 * 1024 * 1024]);
                        Console.Write("#");
                        buffer2.Add(new byte[64 * 1024 * 1024]);
                        Console.Write("#");
                    }
                }
                catch (OutOfMemoryException)
                {
                }
                Console.WriteLine();
                Console.WriteLine("   Total {0} blocks were allocated ( {1} MB).", (buffer1.Count + buffer2.Count), (buffer1.Count + buffer2.Count) * 64);
                
                //        
                //    free  
                //        
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("2. Free Blocks...");
                buffer2.Clear();
                Console.WriteLine("   Total: {0} blocks ({1} MB)", buffer1.Count, buffer1.Count * 64);
    
                //        
                //  GC  
                //            
                GC.Collect(GC.MaxGeneration);  
                     
                //           
                //    allocate  
                //          
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("3. Allocate 72mb block(s) as more as possible...");
                try
                {
                    while (true)
                    {
                        buffer3.Add(new byte[72 * 1024 * 1024]);
                        Console.Write("#");
                    }
                }
                catch (OutOfMemoryException)
                {
                }
                Console.WriteLine();
                Console.WriteLine("   Total: 64mb x {0}, 72mb x {1} blocks allocated( {2} MB).\n", buffer1.Count, buffer3.Count, buffer1.Count * 64 + buffer3.Count * 72);
                Console.ReadLine();
            }
        }
    }
    

    [configuration file]

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>  
      <runtime>    
        <!--<gcConcurrent enabled="false" />-->    
        <!--<gcServer enabled="true" />-->  
      </runtime>
    </configuration>
    

    2008/03/03 系列文章: Memory Management .NET 作業系統 技術隨筆