顯示具有 Dotnet framework 標籤的文章。 顯示所有文章
顯示具有 Dotnet framework 標籤的文章。 顯示所有文章

2013年6月14日 星期五

System.Transactions 裡的 Timeouts 與 Azure 中的設定

在進行交易的過程中,主要有三個 Timeout 時間。而真正的可交易時間,是取下面三者的最小值。

Command.CommandTimeout

這個 timeout 是最基本的 Timeout 時間,預設為 30 秒。這個設定是執行sql指令的可執行時間。

TransactionScope 的Timeout

在執行交易時,TransactionScope 也有一個 Timeout 時間。這個時間是由 TransactionScope 的建構子中的參數來指定的。預設值是60秒,可由 TransactionManager.DefaultTimeout 取得設定值。

TransactionManager 的  MaximumTimeout

TransactionManager 裡頭也有一個 timeout。這個 timeout 時間是是全機的交易管理員的最大可交易的時間。在 .NET 2.0 預設可由子層的 config 或程式來覆寫。但在 .NET 4.0,就不能被子層來覆寫了,如果需要修改,則必須到 %windir%\Microsoft.NET\Framework\v4.0.30319\Config\machine.config (32 位元),或 %windir%\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config 中以管理員的權限進行修改。

<system.transactions>
    <machineSettings maxTimeout="02:00:00" />
</system.transactions>

Azure 中設定

微軟的 Windows Azure Cloud Service 環境中,當然我們可以使用遠端桌面的方式,連線到每個伺服器進行上述的修改。但是一旦重新掛載作業系統後,這些人工設定又全部跑掉必須重設,非常不人道。幸好部署時有 Start Task 的機制, 可以執行 cmd 的指令。cmd 指令如下

windir%\system32\inetsrv\appcmd set config /commit:MACHINE /clr:4 -section:machineSettings -maxTimeout:02:00:00

此指令必須寫成 .cmd 檔,放在 WebRole 或 WorkerRole 的 project 內,以 content/Always copy to Output Directory 的型式加入專案

image   image

接著,在Azure 專案的 ServiceDefinition.csdef 中加上 Startup Task 的指令

<Startup>
  <Task commandLine="timeout.cmd" executionContext="elevated" taskType="simple" />
</Startup>

如下圖

image

其中 executeContext=”elevated” 指的是必須以管理員的權限進行修改

結論

TransactionScope 的 Timeout 設定有點複雜,除了.NET 版本,32/64 版本,%windir%\system32\ 與 %windir%\SysWOW64\ 的不同外,現在又增加了雲端的設定。真是不太容易。

參考

  1. http://stackoverflow.com/questions/1348191/default-transaction-timeout
  2. https://github.com/Aaronontheweb/azure-webroleperformance-scripts
  3. http://blogs.inkeysolutions.com/2012/01/managing-timeouts-while-using.html

2009年8月2日 星期日

patterns & practices Application Architecture Guide 2.0,成為架構師必讀

微軟不斷地提升 .net 的能量,也推出了許多的公開文件。
其中,要讓我們的系統能長長久久地運作下去,好的架構自然是必要選項。

但,系統類型何其多,如 WebForm, WinForm, 甚至 SilverLight,如何作架構設計呢?

patterns & practices Application Architecture Guide 2.0 是您必讀的對象。

2009年6月30日 星期二

如何產生原生格式的 Excel 檔?

產生 Excel 的資料檔,是個老需求了。我也寫過一篇產生 Excel 檔的方法,陳述了我所知道的方法。
我最常使用的方法是 Report Service了,但美中不足的是,Report Service 必須將資料一次吃進來。
我所遇到的資料,有200多萬筆,一次吃進來,當然 Out of memory.

因此,我需要一個直接寫 原生格式的 Excel 檔,而非 csv, xml, html 等格式。

那到底什麼是原生格式呢?找到一個微軟開發的文件,

http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/Excel97-2007BinaryFileFormat(xls)Specification.pdf,怕了吧,共三百多頁!

也有另一個 Open xml 的文件,http://sc.openoffice.org/excelfileformat.pdf,可惜必須以 office 2003 以上來開啟。我的客戶又是Excel 2002,開不了。

現在,找到了一個 open source 的元件, MyXLS,試用一下,還真的很簡單呢!也可支援中文。

可惜,超傷記憶體,寫出70453 筆資料,產生的過程中就使用了 7xx MB。12萬筆,就 out of memory。(我的開發機器,3GB memory,asp.net 最多可用 1.8GB)

其原理是在 memory 組物件,沒有作 swap 到 harddisk的動作。
這個問題,就像 XmlDocument 超傷記憶體一樣,之後才又出了個 XmlTextWriter

不過,若資料筆數少,則這個 MyXLS 可說是相當好用的了。

如果可以的話,想試試 Open XML Format SDK 2.0, 畢竟是微軟自家的東西,想來會比較好用。但現在仍在 CTP,而且 Excel 2002 開不了。

 

20090702 後記:

後來又找到了 NOPI ,看來比 MyXLS 更節省記憶體(26萬筆, 要864MB),且該元件更新頻率較多。比較建議用這個。

微軟不再全力 support OracleClient

根據微軟 ADO.NET Team 的部落格,System.Data.OracleClient Update 提到他們做了一個決定

The Decision

After carefully considering all the options and talking to our customers, partners, and MVPs it was decided to deprecate OracleClient as a part of our ADO.NET roadmap.

 

意思是說,雖然在 .net 4.0 仍然會支援 OracleClient,但會被標示為deprecated (過時,不被建議),請使用 3rd 的元件。

那我們的因應對策呢?新開發案,請使用 ODP.NET,維護案,就維持原來的狀況即可。

2009年6月29日 星期一

伺服應用程式集區 'DefaultAppPool' 的處理序已意外中止了。處理序識別碼為 '6060'。處理序結束碼為 '0x800703e9'。

客戶那裡一直出現這樣的問題。asp.net 1.1 版的程式升級到 2.0 後,速度出奇的慢。

在事件檢視器上,找到了下面的問題。

  1. 伺服應用程式集區 'DefaultAppPool' 的處理序已意外中止了。處理序識別碼為 '6060'。處理序結束碼為 '0x800703e9'。
  2. 事件類型:    警告
    事件來源:    W3SVC
    事件類別目錄:    無
    事件識別碼:    1011
    日期:        2009/6/29
    時間:        上午 10:03:02
    使用者:        N/A
    電腦:    ComputerName
    描述:
    伺服應用程式集區 'DefaultAppPool' 的處理序與 World Wide Web Publishing 服務通訊時發生嚴重錯誤。處理序識別碼為 '3800'。資料欄位含有錯誤號碼。

    請在 http://go.microsoft.com/fwlink/events.asp 查看說明及支援中心,以取得其他資訊。
    資料:
    0000: 6d 00 07 80               m..€   

 

救命啊!即使我在 asp.net 上已在 global.asax 上,在Application_Error上已做好了寫 exception log 的準備,無奈完全看不到任何的 log ,因為在 IIS 上就掛了,來不及讓 asp.net 來寫出log。

怎麼辦呢?解決過程如下。

  1. 在 C:\WINDOWS\system32\LogFiles\HTTPERR 下找到錯誤訊息。
    2009-06-29 08:15:32 172.16.1.87 56735 172.16.1.64 80 HTTP/1.1 POST /myApp/csharpwrapper/Company.WEB.SystemName.FunctionNAme.ClassName,MyApp.ashx?_method=ServerSideGetProductDummy&_session=rw - 1 Connection_Abandoned_By_AppPool DefaultAppPool
  2. 以'0x800703e9' 在 Bing 上追問題,第二個是微軟 msdn上的說明。微軟的問題,當然找微軟的文件。一看,是 stackOverFlow 的 exception.
  3. 再以 Vistual Studio 2008 在 Windows 2003 上 debug,會發現程式碼一如往常,只是跑完ajax 後,就進入的無限迴圈了。

之前同事在 asp.net 1.1 上為了達到 ajax 的效果,使用了一個 open source 的 ajax library,沒想到升級到 2.0後,會造成如此驚人的效果

解法呢?當然是把元兇換掉,讓正牌的 asp.net ajax 上場囉!

2009年6月25日 星期四

Visual Studio 2008, Test not excuted

今天初次使用 Rhino Mocks 來進行單元測試時,發生了下面的問題。

image 

從來沒看過這樣的奇景。
再點擊「Test run error」的連結後,發現有下面的錯誤訊息。

Failed to queue test run 'charles@MOSSDEV 2009-06-25 11:27:20': Test Run deployment issue: The location of the file or directory 'c:\qa2009\qa2009\epmosslibtest\bin\debug\Rhino.Mocks.dll' is not trusted.
原來,此 dll 是從網路來的,是被鎖定住的。按下「解除封鎖」鍵
image

之後,重新打開Visual Studio,重新進行測試後才正常了。

2009年6月18日 星期四

在 GAC上的元件,如何以得到 StackTrace infomation?

一般在開發元件時,通常不會選擇放在 GAC。除了 GAC 需要 strong name 及版本號,需要管理外,也有一個常見的問題:放在 GAC 上的元件,若出現 Exception 時,會得不到在 .pdb 檔上的資訊。

那真的沒辦法嗎?今天終於找到答案。

以 command ,進入 c:\windows\assembly 後,dir 一下,得到下面左邊畫面。

image image

此時你會發現,此目錄結構與檔案總管的不同。(右邊)
再深入一些,你就會發現,原來放到 GAC 的元件,是放到這些目錄的。而且,在 GAC_MSIL 目錄下,出現了一堆的元件,其中,我的元件 EPMossLibrary 就在其中了。
進入子目錄後,就會發現,原來同一個元件,可以有不同的版本、公開金鑰,是因為目錄編排的關係。

image

再進子目錄,就是元件放置的地方。使用 GACUtil 或檔案總管來註冊,只會複製 *.dll 檔的。那就自行使用 dos command: copy 來複製元件 pdb 吧!

image

這樣一來, StackTrace 的資料就有行號了。

2009年6月9日 星期二

該使用哪一種 Mock Object Framework

在撰寫單元測試時,為了降低相依性,必須自行撰寫 mock, stub 等物件。這樣的工作量太大,又不易維護。

於是 smart people 開始發揮想像力與執行力,創造了許多的 Mock Object Framweork.

這一堆的 framework,該用哪一種好呢?尤其是剛入門的我,當然希望採用最多人用的。

參考 http://weblogs.asp.net/rosherove/archive/2007/04/26/choosing-a-mock-object-framework.aspx,發現投票的結果,Rhino Mocks 是最多人使用的了。

image

2009年6月8日 星期一

判斷字串內是否有中文字

這是個老問題了,今天做一個完整的 demo

由於 dotnet framework 內的 string 儲存的是 unicode, 因此我們將字元寫到檔案內,看看哪些字碼是中文字。

      Stream stream = File.Open(@"C:\temp\all.txt", FileMode.Create, FileAccess.Write, FileShare.Read);
      using (StreamWriter sw = new StreamWriter(stream, System.Text.Encoding.Unicode))
        for (int i = 256; i < 65536; i++) sw.WriteLine("{0}:{1}", i, (char)i);

打開 all.txt,發現第一個中文字是 19968 的「一」,最後的中文字是40869的「龥」。

image image

所以呢,所有的中文字都在「一」跟「龥」的範圍之內。
最後,要如何判斷字串內是否有中文字呢?這當然是 regular expression 的工作了。程式碼如下

      Regex ex = new Regex("[一-龥]");
      bool isMatched = ex.IsMatch("jjsss 中文 ksks");  //isMatched will be true

PS: 特別符號,日文等,算不算中文字呢?如果連這些都考慮進來,就有得玩了。跟您的客戶 check 一下吧!

image image

2009年4月6日 星期一

.NET 4.0 是個半新的 .net framework

半新?是什麼意思呢?見下圖便知。
image

V3.0 是架構在 V2.0 的基礎之上。而 V3.0 又是架構在 V2.0 + V3.0 之上。

但 V4.0的執行環境, 是全新的一包。因此執行V4.0時,不需要回頭再找 V2.0, V3.0, V3.5。

既有的程式,已經使用了 V2.0 + V3.0 + V3.5 時,仍然可以 side by side 的執行。

以上圖為例, Outlook 可以執行 V2.0 + V3.0 + V3.5 的這一套,也可以同時執行V4.0 的這一套。

2009年4月2日 星期四

Mix09 KeyNote 筆記

微軟在 Mix09 又 release 了一堆新東西,我又要忙好一陣子了。

Expression Web 3

    SuperPreview, 可在同一介面上看到多個瀏覽器的html 預覽結果與side by side 比較

ASP.NET MVC 1.0

  1. Full Control over HTML markup
  2. SEO friendly with URL routing
  3. Test driven development workflow
  4. Easily extensible

ASP.NET 4 improvements

  1. Web Forms : 可控制 ViewState, Client ID
  2. MVC
  3. AJAX: Client Template, Client side data binding
  4. Distributed Caching

Visual Studio 2010 for web development

  1. Code focused improvments
  2. JavaScript /AJAX /jQuery tooling
  3. SharePoint: 開發與 debug
  4. Publishing and deployment : 除了複製程式外,也可IIS 設定、 create database, update schema

IIS 7 Web Server Extensions

  1. Secure FTP
  2. WebDAV support
  3. proxy

Microsoft Web Platform Installer

  1. Install the latest versions of Microsfot Web Platform tools, server, database and framework
  2. Stay up-to-date and explore what's new
  3. Runs on Windows XP, windows Vista, Windows Server 2003 and Windows Server 2008

Commerce Server 2009

Azure Services Platform

這個在去年的 PDF 已有展示了,而且,我不熟,也不太有興趣。

2008年12月8日 星期一

System.Security.Cryptography.CryptographicException: Key not valid for use in specified state

今日測試時,在下列第二行一直發生System.Security.Cryptography.CryptographicException: Key not valid for use in specified state 的錯誤。中文訊息是「機碼用在特定狀態時無效」

RSACryptoServiceProvider provider = cert.PrivateKey as RSACryptoServiceProvider;

RSAParameters signPrivateKey = provider.ExportParameters(true);

沒看過耶!查了 Google 大神也是無效。
結果,重匯 pfx (即有私鑰的憑證) 就好了?

真是怪

今日證實,是程式寫錯了。
使用provider.ExportParameters(true),即將私鑰匯出,這是不對的。
我只需要將私鑰拿來簽章即可。
如下

      XmlDocument doc = new XmlDocument();
      doc.LoadXml(origXml);

      //匯入私鑰
      X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
      store.Open(OpenFlags.ReadOnly);
      X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbPrint, true);
      if (certs.Count == 0)
        throw new CryptographicException("The certificate could not be found.");

      X509Certificate2 cert = certs[0];

      RSACryptoServiceProvider provider = cert.PrivateKey as RSACryptoServiceProvider;

      SignedXml signXml = new SignedXml(doc);
      signXml.SigningKey = provider;

2008年11月12日 星期三

Framework Design(1) : 建構子應該只傳參數

Constructors are lazy

建構子應該只傳參數。不要在建構時就做了一堆的事。下面的code 就不好。

  public class XmlFile
  {
    string data;
    public XmlFile(string filename)
    {
      data = File.ReadAllText(filename);
    }
  }

該改成下面的事即可

  public class XmlFile
  {
    string filename;
    public XmlFile(string filename)
    {
      this.filename = filename;
    }

    public void DoWork()
    {
      string data = File.ReadAllText(filename);
      //do more
    }

2008年10月17日 星期五

自訂 assembly 的位置

http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.71).aspx  中有描述當CLR程式執行時,載入 assembly 的順序。
因此,可以使用如下的設定,讓程式執時,除了搜尋執行程式的路徑外,也能搜尋自訂的路徑

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="myBin"/>
    </assemblyBinding>
  </runtime>
</configuration>
以上程式執時,會搜尋 .\myBin 下的所有assembly

2008年9月10日 星期三

DebugView

DebugView 是一個好用的 Debug 軟體。
在程式撰寫時,常常被教導要寫

Debug.Write("My debug inforation");

但是,除了在 Visual Studio 內可以看到 debug info 外,其他似乎一無用處了

在執行 .net 程式之前先啟動 DebugView,就可以看到 debug infomation 了

範例

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

class Program
{
  static void Main(string[] args)
  {
    for (int i = 0; i < 1000; i++)
    {
      Stopwatch w = new Stopwatch();
      w.Start();
      TestMethod();
      w.Stop();
      Debug.WriteLine(string.Format("count {0} elapsed {1} msec", i, w.ElapsedMilliseconds));
    }
  }

  private static void TestMethod()
  {
    string[] aColl = File.ReadAllLines(@"c:\a.txt");
    string[] bColl = File.ReadAllLines(@"c:\b.txt");

    var q = from a in aColl
            where !bColl.Contains(a)
            select a;

    foreach (var item in q)
    {
      Console.WriteLine(item);
    }
  }
}

結果如下圖
 image

2008/09/16

在Vista 上執行時,若未使用Run as administrator,會出現如下的錯誤

image

此錯誤將導致無法讀取asp.net 的 debug information

另外,除了必須 Run as administrator,也必須勾選 "Capture Global Win32" 這個選項,才能看到 asp.net 的 debug information

image

2008年8月26日 星期二

Asp.net 網站的模組化開發

一直以來,我們都希望開發網站時,能以模組的型式來開發。部署時,只要部署所需要的模組即可。
列如說,asp.net 應用程式Root 能容納多個模組,分別是公告、訂單、發票三個模組。
開發時,四個專案分別開發(包含asp.net應用程式Root及三個模組)
部署時,可以只部署所需要的模組,如 root + 公告,其餘的不要。

其實,方法已經有了。可見 Creating sub-projects in IIS with Web Application Projects
這樣的方式好處是簡單,而且可以分開部署。
可是,如果要談到資料交換(root 與 模組,模組與模組) 的資料交換,就又顯得複雜了。
只能靠 Session 或 database 來交換資料,並不是很好的做法。

目前我知道最好的做法,是 Web Client Software Factory, WCSF。

它不但可以模組與模組之間交換,甚至可以有依賴關係,例如公告模組依賴於權限模組。
並且又加上了 page flow (可取代之前的 User Interface Process (UIP) Application Block),還設計了權限、ObjectContainerDataSource、realtime search
連 source code 都給你了,真是物超所值。

2008年8月19日 星期二

SingleTagSectionHandler

 

使用 configuration 時,常常為了如何配置檔案而傷腦筋。

如果全部使用 appSettings,則設定將會很雜亂而難以維護。
如果使用自訂的 ConfigurationElement, 又會產生程式碼需要維護的問題。

在.net 2.0 有個很好用的 SingleTagSectionHandler 可以使用。
配置檔如下。

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="MySection" type="System.Configuration.SingleTagSectionHandler"/>
  </configSections>
  <MySection key1="A" key2="B" key3="C"/>
</configuration>

讀設定時,可以用下面的方法讀出資料

      Hashtable ht = ConfigurationManager.GetSection("MySection") as Hashtable;
      string key1 = ht["key1"].ToString();
      string key2 = ht["key2"].ToString();
      string key3 = ht["key3"].ToString();
code download

2008年8月6日 星期三

DateTime.Parse("中華民國97年2月29日")?

同事問到,如何將 "中華民國97年2月29日" 的字串轉成 DateTime, 與將 DateTime 輸出成 "中華民國97年2月29日"

沒遇過這個問題。

打開 MSDN, 找到了 TaiwanCalendar

開始寫程式囉

      DateTime dt = new DateTime(2008, 2, 29);
      TaiwanCalendar c = new TaiwanCalendar();
      CultureInfo ci = new CultureInfo("zh-TW", true);
      ci.DateTimeFormat.Calendar = c;
      Thread.CurrentThread.CurrentCulture = ci;
      Console.WriteLine(dt.ToLongDateString());

      DateTime dt2;

      dt2 = DateTime.Parse("97-02-29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97/02/29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97-2-29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("97|02|29", "yy|MM|dd", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("中華民國97年2月29日", "中華民國yy年M月dd日", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("中華民國97年2月29日", "中華民國yy年M月dd日", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97/02/29 下午 3:46:01");
      Console.WriteLine(dt2.ToString());

輸出的結果如下
97年2月29日
97年2月29日
97年2月29日
97年2月29日
97年2月29日
97年2月29日

sample code download here

2008年7月25日 星期五

Windows Form 的 Exception 處理

之前對於 WinForm 的 Exception 處理方法,一直搞不懂。
原來,微軟有 sample

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors to go through
    // our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

 

也就是說,UI Thread 上發生的錯誤,會產生 Application.ThreadException 事件
而非 UI Thread 上發生的錯誤,則會產生 AppDomain.CurrentDomain.UnhandledException 事件

2007年8月29日 星期三

SecurityAction

SecurityAction 的 enum 值真是怪,不知道是誰取的名 SecurityAction.RequestMinimum:要求assembly至少要有這個權限。如果assmebly 沒有符合這個要求,會產生 Security.Policy.PolicyException。名字應該改成 RequireMinimum 才對。 SecurityAction.RequestOptional:拒絕所有不在SecurityAction.RequestMinimum 及SecurityAction.RequestOptional 的權限。如果不符合,並不會產生 exception。名字應改成 RefuseAllExcept 才對。 SecurityAction.RequestRefuse:正面列出不要的權限。也就是說,如果有這個權限,也拒絕執行。如果不符合,並不會產生 exception。例如我確定不要連sql server,應該在 SqlClientPermission 上設 SecurityAction.RequestRefuse。

Share with Facebook