顯示具有 核心程式設計 標籤的文章。 顯示所有文章
顯示具有 核心程式設計 標籤的文章。 顯示所有文章

2009年12月20日 星期日

IsolatedStorage

命名空間:System.IO.IsolatedStorage
組件:mscorlib.dll
IsolatedStorage類別:所有隔離儲存區的基底類別(抽象類別)

IsolatedStorageFile類別:表示含有檔案和目錄隔離儲存區

IsolatedStorageScope enumeration:列舉IsolatedStorage所支援的隔離儲存區範圍層次

IsolatedStorageFileStream類別:公開隔離區(Isolated Storage)中的檔案
  • Application 範圍限定於應用程式的隔離儲存區。
  • Assembly 範圍限定於組件 (Assembly) 識別 (Identity) 的隔離儲存區。
  • Domain 範圍限定於應用程式定義域識別的隔離儲存區。
  • Machine 範圍限定於電腦的隔離儲存區。
  • None 沒有隔離儲存區的使用。
  • Roaming 隔離儲存區可以放置在可能漫遊的檔案系統某一處 (如果漫遊使用者資料在基礎作業系統中啟用)。
  • User 由使用者識別限定範圍的隔離儲存區。
C#
Example 1
IsolatedStorageFile isoFile =
IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain,
null,
null);

IsolatedStorageFileStream isoStream =
new IsolatedStorageFileStream(this.userName,
FileMode.Open,
FileAccess.Read,
FileShare.Read);

Example 2

IsolatedStorageFile isoFile;
private void Form1_Load(object sender, EventArgs e)
{
isoFile = IsolatedStorageFile.GetMachineStoreForDomain();
}

private void button1_Click(object sender, EventArgs e)
{
String fileName = textBox1.Text;
try{
using (FileStream fs= new IsolatedStorageFileStream(fileName,
FileMode.Open, FileAccess.Read, isoFile))
{
StreamReader sr = new
StreamReader(fs,Encoding.GetEncoding("big5"));
textBox2.Text=sr.ReadToEnd();
sr.Close();
}
}catch(Exception ex){
MessageBox.Show(ex.Message);
}
}


MarshalByRefobject

MarshalByRefobject類別
  啟用在支援Remoting Application中跨越Application domain boundaries中的存取。
命名空間:System
組件:mscorlib.dll
有兩種型態的遠端物件
  • Marshal-by-value objects:藉由「值」,這些物件被複製和傳遞,傳出應用程式定義域
  • Marshal-by-reference objects:藉由使用「Proxy」這些物件被存取外部應用程式定義域。Client需要「Proxy」來使用這些物件,去存取這些遠端的物件。

當跨越應用程式定義域界限來使用型別時,型別必須繼承自 MarshalByRefObject,並且不可以複製物件的狀態,因為物件的成員無法在建立成員的所在應用程式定義域外部使用。

using System;
using System.Runtime.Remoting;
using System.Security.Permissions;
public class SetObjectUriForMarshalTest {
class TestClass : MarshalByRefObject {
}
[SecurityPermission(SecurityAction.LinkDemand)]
public static void Main() {
TestClass obj = new TestClass();
RemotingServices.SetObjectUriForMarshal(obj, "testUri");
RemotingServices.Marshal(obj);
Console.WriteLine(RemotingServices.GetObjectUri(obj));
}
}

2009年10月26日 星期一

檔案系統

檔案系統
1、檔案系統的類別
(1)FileSystemInfo類別
(2)FileInfo類別
(3)DirectoryInfo類別
2、DriveInfo類別
(1)Drive Type列舉常數
3、FileSystemWatcher類別

說明:將介紹檔案系統,包含如何透過.NET的類別取得目錄、檔案以及系統磁碟清單。
  • 檔案系統的類別
  • 存取磁碟資訊
  • 監控檔案目錄

最近試著想寫寫看我的電腦,這部份是為了活用之前學習的檔案系統,順手就記了下來

//宣告DriveInfo類別物件,使用getDrives方法取得
//系統所有邏輯磁碟機的DriveInfo類別型態
//直接加入tscbo_DriveList.Item裡
DriveInfo[] drivesInfo = DriveInfo.GetDrives();
tscbo_DriveList.Items.Add("我的電腦");

tscbo_DriveList.Items.AddRange(drivesInfo);

//foreach寫法
if (tscbo_DriveList.SelectedItem.ToString() == "我的電腦")
{
DriveInfo[] dri = DriveInfo.GetDrives();
lst_Detail.Clear();

foreach (DriveInfo tempdri in dri)
{
lst_Detail.Items.Add(tempdri.Name);
}

}

//宣告DirectoryInfo類別物件並指定路徑參數
DirectoryInfo dir = new DirectoryInfo(tscbo_DriveList.SelectedItem.ToString());

if (dir.Exists)
{

lst_Detail.Clear();
//利用GetDirectories()方法列出子路徑
foreach (DirectoryInfo tempDir in dir.GetDirectories())
{
lst_Detail.Items.Add(tempDir.FullName.Substring(
tscbo_DriveList.SelectedItem.ToString().Length,
tempDir.FullName.Length - tscbo_DriveList.SelectedItem.ToString().Length));
}
//利用GetFiles()方法列出檔名
foreach (FileInfo tempDir in dir.GetFiles())
{
lst_Detail.Items.Add(tempDir.FullName.Substring(
tscbo_DriveList.SelectedItem.ToString().Length,
tempDir.FullName.Length - tscbo_DriveList.SelectedItem.ToString().Length));
}

}

//取得特殊資料夾的所在目錄
string DesktopDir = System.Environment.GetFolderPath(
Environment.SpecialFolder.DesktopDirectory);
DirectoryInfo dir = new DirectoryInfo(DesktopDir);

//AllUsersApplicationData 取得路徑名稱,該路徑指向 \Documents and Setting\All //Users\ApplicationData 目錄中的應用程式資料。
//CurrentUserApplicationData 取得路徑名稱,該路徑指向 [CurrentApplicationData] 目錄。
//Desktop 取得路徑名稱,該路徑指向桌面目錄。
//MyDocuments 取得路徑名稱,該路徑指向 [MyDocuments] 目錄。
//MyMusic 取得路徑名稱,該路徑指向 [My Music] 目錄。
//MyPictures 取得路徑名稱,該路徑指向 [My Pictures] 目錄。
//ProgramFiles 取得路徑,該路徑指向 [Program Files] 目錄。
//Programs 取得路徑名稱,該路徑指向 [Programs] 目錄。
//Temp 取得路徑名稱,該路徑指向 [Temp] 目錄。

2009年10月2日 星期五

IsolatedStorageFile取得該相對應隔離儲存區範圍
  • IsolatedStorageFile.GetMachineStoreForApplication:取得對應於呼叫程式碼的應用程式識別之機器範圍隔離儲存區。
  • IsolatedStorageFile.GetMachineStoreForAssembly:取得對應於呼叫程式碼的組件識別之機器範圍隔離儲存區。
  • IsolatedStorageFile.GetMachineStoreForDomain:取得對應於應用程式定義域識別和組件識別的機器範圍隔離儲存區。
  • IsolatedStorageFile.GetUserStoreForApplication:取得對應於呼叫程式碼的應用程式識別之使用者範圍隔離儲存區。
  • IsolatedStorageFile.GetUserStoreForAssembly:取得對應於呼叫程式碼的組件識別之使用者範圍隔離儲存區。
  • IsolatedStorageFile.GetUserStoreForDomain:取得對應於應用程式定義域識別和組件識別的使用者範圍隔離儲存區。

2009年9月24日 星期四

自訂安裝程式

自訂安裝程式
  • Setup專案只能進行一般的安裝作業(一般應用程式、Web應用程式...等包裝程式的包裝作業)
  • 額外的安裝作業必須撰寫自訂安裝程(ex:安裝軟體順便安裝資料庫)
  • 自訂安裝程式有哪些
1、撰寫Script-vbs、js
2、一般執行檔-exe
3、撰寫可配合Setup專案安裝的Installer類別
=====================================================================
認識Installer類別
  • 提供專案的安裝程序
  • 簡化使用者安裝流程
  • 允許在安裝過程中詢問用程式的初始化設定
  • 如何撰寫Installer
1、繼承Installer類別
2、覆寫Install、Commit、Rollback及Uninstall方法
3、加入RunInstallerAttribute
4、將寫好的類別放到安裝程式中
5、執行安裝程式
=>Installer類別是自訂安程式的基底類別,隨著自訂安裝的需求可以覆寫以下類別
  • Install:在安裝程序時進行的程式
  • Commit:在完成安裝程式並確認安裝成功時進行程式
  • Rollback:在安裝失敗後將環境復原到原狀時所需進行的程式
  • Uninstall:在移除程式時進行的程式。
=>Installer的延伸類別可以透過安裝程式工具Installutil.exe及Setup專案上執行。
=>RunInstallerAttribute:預設為false。若設成true表示安裝程式可以讓Installutil.exe及Setup專案進行安裝作業。
=====================================================================
如何撰寫Installer類別
1、建立Class Library專案
2、加入參考Add Reference項目System.Configuration.Install
3、加入類別
4、繼承Installer

自訂Section區段(CustomConfig)(M08)

自訂Section區段
  • 使用時機:.Net Framework內定的Section不符合使用時

1、新增一個Departement區段,代表應用程式的使用部門

2、使用類別物件(新的Class),以便於後續開發者方便存取這個設定檔的內容
Public Class Department
Public Name As String
Public Manager As String
End Class

3、
建立一個實作IConfigurationSectionHandler介面的類別(新的Class),用來實作IConfigurationSectionHandler介面。使用Create方法,以取得組態區段中的attribute、element。
  • 第一個參數為父項物件,型別為Object
  • 第二個參數為組態內容物件,型別為Object
  • 第三個參數為區段的XML節點,型別為XmlNode

Imports System.Configuration
Public Class DepartmentHandler
Implements IConfigurationSectionHandler

Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object Implements System.Configuration.IConfigurationSectionHandler.Create
Dim dept As New Department
dept.Name = section.SelectSingleNode("Name").InnerText
dept.Manager = section.SelectSingleNode("Manager").InnerText
Return dept
End Function

End Class
4、必須在專案中的app.Config組態檔的區段中宣告Department型別

"Mod08_Section.DepartmentHandler,Mod08_Section"
專案名稱.處理Department類別名稱,專案名稱

5、取出自訂Section區段,使用Confurationmanager類別的GetSection方法取的Department區段再轉型為Department類別,即可使用存取
Imports System.Configuration

Dim dep As Department = CType(ConfigurationManager.GetSection("Department"), Department)
TextBox1.Text = dep.Name
TextBox2.Text = dep.Manager




2009年9月22日 星期二

使用ConfigurationManager管理組態檔

使用ConfigurationManager管理組態檔
命名空間
  • System.Configuration
方法
  • OpenExeConfiguration:開啟執行中應用程式的組態檔
  • OpenMachineConfiguration:開啟本機Machine.config的組態檔
  • AppSettings:取得目前應用程式的設定資訊
  • ConnectionString:取得目前應用程式的連線字串資訊
==================================
組態檔除了可以使用文字編輯器手動編輯外,也可以利用程式碼進行控制。
ConfigurationManager可以讓程式存取本機、應用程式、使用者的組態資訊。

組態檔的使用者層級
在開啟應用程式時可以指定使用者階級,它的列舉常數名稱是ConfigurationUserLevel,包含下列列舉值:
  • None:取得套用給全部使用者的組態資訊
  • PerUserRoaming:取得套用給目前使用者的漫遊(Roamining)組態資訊
  • PerUserRoamingAndLocal:取得用給目前使用者的本機組態資訊
=>漫遊(Roamining)在網域(Domain)環境中,使用者允許漫遊於網域中其它電腦,而使用者設定檔會隨著使用者的登入而更新到登入的那台電腦。
==================================
如何開啟組態檔
  • 開啟應用程式的組態檔
config = ConfigurationManager.OpenExeConfiguration( _
ConfigurationUserLevel.None)
TextBox1.Text = config.FilePath
=>D:\NET\U2956A\Exercise\Mod08\Mod08\bin\Debug\Mod08.vshost.exe.config
  • 開啟本機的組態檔
config = ConfigurationManager.OpenMachineConfiguration
TextBox2.Text = config.FilePath
=>c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Config\machine.config
==================================
開啟應用程式組態檔的步驟如下:
1、專案須參考System.Configuration組件
2、匯入System.Configuration命名空間
3、宣告ConfigurationManager
4、呼叫ConfigurationManager類別所提供的靜態方法OpenExeConfiguration
==================================
如何存取組態
  • 修改組態檔

==================================
appSettings區段的組態存取
Windows應用程式專案必須自行開啟app.Config檔案編輯。
=>測試要到D:\NET\U2956A\Exercise\Mod08\Mod08\bin\Debug\Mod08.exe測試才會準
=>如用D:\NET\U2956A\Exercise\Mod08\Mod08\bin\Debug\Mod08.vshost.exe修改組態檔會沒有效果

程式實作
'寫入
Dim config As Configuration
config = ConfigurationManager.OpenExeConfiguration( _
ConfigurationUserLevel.None)
config.AppSettings.Settings("FileServer").Value = TextBox6.Text
config.Save()
'讀取
TextBox6.Text = config.AppSettings.Settings("FileServer").Value
==================================
connectionStrings區段的組態存取
'寫入
Dim config As Configuration
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)
config.ConnectionStrings.ConnectionStrings("Mod08.My.MySettings.cnToNorthwind").ConnectionString = TextBox7.Text'可修改application層級
config.Save()
'讀取
TextBox7.Text = ConfigurationManager.ConnectionStrings( _
"Mod08.My.MySettings.cnToNorthwind").ConnectionString'如用ConfigurationManager修改Application層級會顯示只能唯讀錯誤

使用工具編輯應用程式組態檔(M08)

使用工具編輯應用程式組態檔
Web專案

  • WebSite->ASP.NET Configuration
  • 連線字串、應用程式組態、安全性…
Windows專案
  • Solution Explorer選取My Project按滑鼠右鍵選取Open
  • 連線字串
  • 應用程式組態
Window應用程式組態項目分成二個存取範圍
  • Application:指應用程式所有的使用者共享的組態資訊,像是連線字串,應用程式專屬的環境變數。
  • User:指應用程式登入使用者的個別組態資訊,每個使用者都可以有自己的組態設定值,並且存在系統的使用者設定檔中「C:\Document and Settings\[使用者]\Local Settings\Application Data\[公司名稱]\[組件].exe_Url_[GUID]\版本\user.config
=====================================================
如何存取Application/User範圍的組態項目
  • Visual Basic使用My的Settings類別
Visual Basic TextBox1.Text=My.Settings.CompanyName

  • C#使用專案根命名空間的Properties.Settings
C# TextBox1.Text=WinConfig.Properties.Settings.Default.CompanyName;

存取Application範圍的組態項目
Application範圍的組態項目:只能讀取。
User範圍的組態項目:允許讀寫的項目。

程式實例

Imports System.Configuration
'寫入
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
My.Settings.ForeColor = Color.FromName(TextBox2.Text)
My.Settings.BackColor = Color.FromName(TextBox3.Text)
End Sub
'讀取
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TextBox1.Text = My.Settings.CompanyName
TextBox2.Text = My.Settings.ForeColor.Name
TextBox3.Text = My.Settings.BackColor.Name
End Sub

2009年9月21日 星期一

Shared Assembly VS Private Assembly(M08)

私有組件與共享組件
共享組件(Shared Assembly)
1、要有StrongName,Version
2、載入檢查SimpleName, StrongName,Version
3、可放在任何位置除了CAS(Global Assembly Cache在「系統磁碟:\WINDOWS\assembly」位置下)以外的位置要寫設定檔

共享組件設計步驟:
共享組件必須有強式名稱(Strong-Name),強式名稱組件的設定如下:
1、Solution Explorer上選取My Project按滑鼠右鍵選取「Open」
2、在專案屬性頁上選取(左邊)「Signing」(簽署),並勾選「Sign the assembly」(簽署組件)

3、在「Choose a strong name key file:」下拉選項選,接著會出現「Create Strong Name Key」視窗,在此視窗的「Key file name:」輸入強式名稱金鑰的檔名,並清除「Protect my key file with a password」。

================================================
私用組件(Private Assembly)
1、載入時只檢查SimpleName
2、必須放在應用程式所在的目錄或子目錄下
3、若放Application所在的子目錄必須寫設定檔
=>.NET預設是私有組件(Private Assembly),必須與應用程式放在同一個目錄下。
=============================================================
開發階段用來取代GAC組件
  • 避免開發週期不斷的將組件重新置放到GAC
步驟
  • 設定環境變數DEVPATH
  • 組態檔指定developmentMode

如何新增環境變數
1、在「我的電腦」上按滑鼠右鍵選取「內容」,點選「進階」頁籤,按「環境變數」按鈕。
2、在「環境變數」視窗上選取「新增」。
假設您正在建置 (Build) 稱為 SharedAssembly 的共用組件,而輸出目錄為 D:\SharedAssembly\Debug。您可以將 D:\SharedAssembly\Debug 放在 DEVPATH 變數中。
3、您必須接著在電腦組態檔中指定項目。這個項目會告訴 Common Language Runtime 要使用 DEVPATH 來找出組件。

developerInstallation:指定執行階段是否在 DEVPATH 環境變數所指定的目錄中搜尋組件。true:在 DEVPATH 環境變數所指定的目錄中搜尋組件。


2009年9月17日 星期四

組態及安裝應用程式(M08)

認識.NET Framework2.0的組態檔
  1. XML格式的檔案
  2. 用來設定應用程式的連結字串、安全性、應用程式的環境組態及版本控制
  3. 本機層級(Machine.config,預設儲存於[安裝磁碟]:\WINDOWS\Microsoft.Net\Framework\版本\CONFIG)
  4. 應用程式層級(一般應用程式:組件名稱.exe.config,一般應用程式組態檔必須和執行檔放在相同目錄、Web應用程式:Web.config)
  5. 編修方式有文字編輯器、MMC管理工具、Visual Studio 2005提供的工具、ConfiguratonManager類別
=========================================================
.Net Framework執行階段的版本控制
  • 電腦同時有.Net1.0、.Net1.1而未寫組態檔的情況
一般應用程式或組件在什麼版本下建置,程式執行時在執行組件當時所建置的版本。

=========================================================
.NET Framework執行版本控制
  • 只支援.NET1.0版
=>.NET Framework 1.0所建置的應用程式,必須使用requiredRun指定應用程式所支援的.NET Framework版本。requiredRuntime的version:指定版本;safemode:指定程式碼是否援譣註冊機碼以決定Runtime版本,預設為false,設為true時代表不搜尋註冊機碼







  • 支援.NET1.1以後版本
=>.NET framework1.1(含)以後建置的應用程式,必須使用supportedRuntime指定應用程式所支援的Runtime版本。






===========================
NET1.0=>V.S.2002
NET1.1=>V.S.2003
NET2.0=>V.S.2005
NET3.5=>V.S.2008(2.0、3.0、3.5)
===========================
=>.NET Framework2.0版所建置的應用程鋨只能在有.NET Framework2.0的環境執行,原因是大量引進新的類別與指令,舊版Runtime不支援。
=>.NET Framework1.0版所建置的應用程式通常可以在.NET Framework 1.0、1.1、2.0的環境上執行。.NET Framework1.1通常也可以在.NET Framework1.1、2.0上執行。但必須實際上測試才知道。

使用SortedList集合(M03)

使用SortedList集合
  • 可使用數值索引(Index)和Key值存取集合中的項目
  • 類似HashTable與Array的組合體
  • 內部維護兩個陣列(以key排序的陣列和以Value排序的陣列)
  • 根據Key值進行排序
使用SortedList物件的考量
SortedList是Key/value配對所成的集合,以key值排序,可以利用key或索引存取其中的項目。當新增時,會適當進行排序,因此建立SortedList成本是相當昂貴的。
適用SortedList情境
  • 當資料變動性不大時,新增、刪除集合項目不頻繁,或資料量不大時。
  • 要快速利用索引值,或key值讀取集合中的項目時。
  • 需要排序的項目,或查詢特定物件時。
避免使用SortedList情境
  • 集合中的項目大量變動時,因為新增項目之後需排序,需花費很久時間。若變動性大,不如改成ArrayList,它也提供排序功能,但花費的時間比SortedList少。
  • 不要使用SortedList排序字串,會額外花費轉型的負擔,若有需要排序字串,可以改用StringCollection集合。
==================================================
使用StringCollection集合
  • 定義在System.Collections.Specialized命名空間
  • StringCollection集合
=>位於System.Collections.Specialized命名空間之下
=>許多字串所成的集合
  • StringDictionary集合
=>內部實作一個HashTable
=>每個項目是一個DictionaryEntry物件

2009年9月16日 星期三

HashTable VS HybridDictionary(M03)

使用HashTable
  • Key/Value成對出現的資料結構。
  • 項目存放的順序,和加入的先後次序無關,內部項目排列順序是根據HashCode排序。
  • 索引鍵可以是文字或數值。
=>因為Hashtable中項目沒有按新增的順序排列,因此新增、行除項目的方法只能使用Add、Remove方法。Clear可以清除所有項目

程式實作
Module Module1

Sub Main()
Dim ht As Hashtable = New Hashtable
ht("10") = "Mary"
ht("20") = System.DateTime.Now
ht("30") = 100

For Each o As DictionaryEntry In ht
Console.WriteLine("Key:{0}-->Value:{1}", o.Key.ToString, o.Value.ToString)
Next
ht.Remove("10")

End Sub

End Module

使用Hashtable的考量
  • 適用在變動程度高,以及不易變動資料上。當然由於Hashtable根據Hash Code排序,資料變動的程度高代表要額外花費計算hash值的成本。
  • 如果集合中項目少於10個,使用ListDictionary來存放Key/Value配對所成的集合,可得較佳的效能。
=====================================================
使用HybridDictionary
  • 位於System.Collections.Specialized命名空間之下
  • 集合中的項目需要Key/Value配對出現
  • 內部用來儲存資料的物件(項目少:使用ListDictionary;項目多:使用HashTable)
  • 適合在無法預期集合中的資料量時
  • 不適用在排序

使用Stack VS Queue(M03)

使用堆疊(Stack)

1、循序存取集合中的項目
2、後進先出(LIFO)類型的資料架構
3、常用方法
  • Push:新增一個項目到頂端。
  • Pop:從Stack頂端取出一個項目。
  • Peek:允許檢視堆疊頂端上的項目,但不將之移除。若在空的堆疊上呼叫Peek,會觸發InvalidOperationException
程式實作
Module Module1

Sub Main()
Dim st As New Stack
st.Push(1)
st.Push(2)

Dim nIndex As Integer = 0

For Each o As Object In st
Console.WriteLine("移除前Queue->{0}:" + ControlChars.Tab + "{1}", nIndex, o.ToString)
nIndex = nIndex + 1
Next o
st.Pop()

nIndex = 0

For Each o As Object In st
Console.WriteLine("移除後Queue->{0}:" + ControlChars.Tab + "{1}", nIndex, o.ToString)
nIndex = nIndex + 1
Next o
st.Clear()

End Sub

End Module

使用Stack考量
  • 需以後進先出時。
  • 使用完資料之後就可以丟棄此資料項目時。
  • 建立時最好設定初始的容量(Capacity),避免無意義的浪費記憶體。
=====================================================
使用佇列(Queue)
1、先進先出(FIFO)類型的資料結構
2、常見方法
  • Enqueqe:新增一個項目到Queue的後面。
  • Dequeue:從Queue中移除一個項目,並回傳目前被移除的這個項目。若從空的佇列中移除一個項目會觸發InvalidOperationException例外。
  • Clear:清除所有項目。
  • Peek:查詢第一個項目,不移除此項目。若從空的佇列中呼叫Peek方法,一個項目會觸發InvalidOperationException例外。
3、常見屬性
  • Count:回傳此Queue有多少個項目。
程式實作
Sub Main()
Dim q As New Queue
q.Enqueue(1)
q.Enqueue(2)
q.Enqueue(3)
Dim nIndex As Integer = 0
For Each o As Object In q
Console.WriteLine("Queue->{0},{1}", nIndex, q.ToArray(nIndex).ToString)

nIndex += 1
Next
End Sub

使用Queue的考量
  • 需使用先進先出時
  • 為循序資料時

DataSet序列化(M04)

1、使用DataSet內建方法
  • WriteXML方法:將DataSet寫成XML檔
  • ReadXML方法:將XML檔還原為DataSet
  • GetXML方法:取得序列化後的XML字串資料
2、控制DataSet序列化格式
  • 修改DataSet的DataSetName屬性
  • 修改DataTable的DataTable屬性
  • 修改DataColumn的ColumnName屬性
  • 修改DataColumn的ColumnMapping屬性
===================================
程式實作
Public Class Form1

Private Sub JobsBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles JobsBindingNavigatorSaveItem.Click
Me.Validate()
Me.JobsBindingSource.EndEdit()
Me.JobsTableAdapter.Update(Me.PubsDataSet.jobs)

End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: 這行程式碼會將資料載入 'PubsDataSet.jobs' 資料表。您可以視需要進行移動或移除。
Me.JobsTableAdapter.Fill(Me.PubsDataSet.jobs)

End Sub
Public ds As New pubsDataSet
Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripWriteDataSet.Click
Me.JobsTableAdapter.Fill(Me.ds.jobs)
ds.DataSetName = "工作列表"
For Each dc As DataColumn In ds.Tables(0).Columns
dc.ColumnMapping = MappingType.Attribute

Next
ds.Tables(0).Columns("job_id").ColumnName = "工作編號"
ds.WriteXml(Application.StartupPath & "\DataSet.xml")
End Sub

Private Sub ToolStripButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripReadDataSet.Click
ds.Clear()
ds.ReadXml(Application.StartupPath & "\DataSet.xml")
MessageBox.Show("共讀取到" & ds.Tables(0).Rows.Count.ToString & "筆資料")
End Sub

Private Sub ToolStripButton3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripGetDataSet.Click
MessageBox.Show(ds.GetXml)
End Sub
End Class

SOAP序列化(M04)

SOAP序列化
SOAP(Simple Object Access Protocol)標準定義基本物件型別的XML描述方法,也定義了遠端程序呼叫的標準。
SOAP序列化和反序列化物件
SOAP結合XML序列化和Binary序列化的兩個重要特性,一是格式為標準XML,具備跨網際網路的特性,二是對於Private資料也能夠保存。
=====================
1、參考System.Runtime.Serialization.formatters.Soap.dll
2、SOAP序列化和反序列化物件
  • System.Runtime.Serialization.Formatters.Soap
  • 使用Formatter物件
  • 使用Stream物件
  • 呼叫Serialize和Deserialize方法
========================================
Public Class Person
Public strName As String = "Jerry"
Private intAge As Integer = 18
End Class
=====================

Imports System.Runtime.Serialization.Formatters.Soap
Imports System.IO
Public Class Form1


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'1、建立及使用物件
Dim obj As New Person


'2、序列化SOAP物件
Dim Formatter As New SoapFormatter()
Dim fs As New FileStream(Application.StartupPath & "\Person.xml", FileMode.Create)

Formatter.Serialize(fs, obj)
fs.Close()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'3、反序列化還原物件
Dim Formatter As New SoapFormatter()
Dim fs As New FileStream(Application.StartupPath & "\Person.xml", FileMode.Open)
Dim obj As Person = CType(Formatter.Deserialize(fs), Person)
fs.Close()
MessageBox.Show("Deseriablize OK...Name = " & obj.strName)

End Sub
End Class

2009年9月13日 星期日

序列化(M04)_Binary VS XML

序列化是一種轉換記憶體的物件資料格式技術,目的在於將物件資料轉換成可以保存於檔案或其他儲存位置的技術,方便未來將物件資料保存或傳送。
  • 跨AppDomain時使用
何謂序列化與反序列化
序列化技術同時也包含反序列化方法,當物件資料序列化成資料串流(Stream)格式,藉由網路送到其他位置時,需使用反序列化的方法將之還原成物件方能繼續使用物件

.NET相關序列化技術
1、Binary Serialization
  • 提供物件的完整型別保存,通常用鄉跨不同應用程式之間的物件交換ex:剪貼簿可將物件序列化後放進剪貼簿,就像應用程式關閉,也可從剪貼簿反序列化到另一個應用程式使用。
  • 將物件序列化之後可以轉換到 資料串流、硬體或記憶體,透過網路就可和各應用程式交換資料。ex:Romoting技術就是依靠序列化技術完成遠端呼叫的資料傳遞。
Binary Serialization實作
(1)建立一個可序列化的類別
  • 套用Serializable Attribute
  • 套用NonSerialized Attribute
(2)序列化及反序列化物件
  • System.Runtime.Serialization.Formatters.Binary
  • 使用Formatter物件
  • 使用Stream物件
  • 呼叫Serialize與Deserialize方法

Imports System.Runtime.Serialization.Formatters.binary
Imports System.IO

Public Class BinaryClass
Private Name As String = "Jerry"
Private Age As Integer = 10
Private Birthday As Date

Public Property strName() As String
Get
Return Name
End Get
Set(ByVal value As String)
Name = value
End Set
End Property

Public Property intAge() As Integer
Get
Return Age
End Get
Set(ByVal value As Integer)
Age = value
End Set
End Property

Public Property dateBirthday() As DateTime
Get
Return Birthday
End Get
Set(ByVal value As DateTime)
Birthday = value
End Set
End Property
End Class

=====================
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

Public Class Form1
'1、建立物件及使用物件
Dim People As New BinaryClass()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

People.strName = "Jerry"
People.intAge = 18
People.dateBirthday = "2009/09/15"

'2、將序列化成Binary檔案
Dim formatter As New BinaryFormatter()
Dim fs As New FileStream(Application.StartupPath & "People.bin", FileMode.Create)
formatter.Serialize(fs, People)
fs.Close()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'3、反序列化為物件
Dim formatter As New BinaryFormatter
Dim fs As New FileStream(Application.StartupPath & "People.bin", FileMode.Open)
Dim obj As BinaryClass = CType(formatter.Deserialize(fs), BinaryClass)
fs.Close()
Messagebox.Show("Deserialize OK...Private strName" & obj.strName)
'MessageBox.Show(Application.StartupPath & "People.bin")
End Sub
End Class
========================================
2、XML Serialization
  • 只保存物件當中Public的成員資料與成員屬性,不保證資料完整性,通常應用在單純的資料保存及傳遞,且由於序列化後資料格式為XML,為一個開放的標準,適合於現今的網路中。
  • 但因XML格式完全開放自行定義,會導致不相容於所有應用程式的情況發生,而SOAP標準就成為應用程式之前XML資料格式的標準了,讓資料更具通透性。
XML Serialization實作

(1)建立一個類別包含Public的資料
(2)XML序列化和反序列化物件
  • System.Xml.Serializtion
  • 使用Stream物件
  • 呼叫Serialize與Deserialize方法

Public Class MyBook
Public bookID As Integer
Public bookName As String
End Class
=====================
Imports System.IO
Imports System.Xml.Serialization
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'1、建立及使用物件
Dim obj As New MyBook
obj.bookID = 10
obj.bookName = "琦真說童年"
'2、序列化XML物件
Dim ser As New XmlSerializer(GetType(MyBook))
Dim fs As New FileStream(Application.StartupPath & "\MyBook.xml", FileMode.Create)
ser.Serialize(fs, obj)
fs.Close()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'3、反序列化還原物件
Dim ser As New XmlSerializer(GetType(MyBook))
Dim fs As New FileStream(Application.StartupPath & "\MyBook.xml", FileMode.Open)
Dim obj As MyBook = CType(ser.Deserialize(fs), MyBook)
fs.Close()
MessageBox.Show("Deseriablize OK...PublicBookName = " & obj.bookName)
End Sub
End Class
========================================
使用Attribute控制XML序列化
(1)建立一個類別包含Public資料
(2)XML序列化及反序列化物件
(3)如何使用Attribute控制XML序列化
  • System.Xml.Serialization Namespace
  • XmlRoot Attribute
  • XmlElement Attribute
  • XmlAttribute Attribute
(4)控制陣列型別的序列化
  • XmlArray Attribute
  • XmlArrayItem Attribute
=====================
Imports System.Xml.Serialization

Public Class MyProduct
Public productID As Integer
Public productName As String
End Class
=====================

Imports System.IO
Imports System.Xml.Serialization
Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'1、建立及使用物件

Dim obj As New MyProduct
obj.productID = 123
obj.productName = "可愛小寶具"


'2、序列化XML物件
Dim ser As New XmlSerializer(GetType(MyProduct))
Dim fs As New FileStream(Application.StartupPath & "\MyProduct.xml", FileMode.Create)
ser.Serialize(fs, obj)
fs.Close()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'3、反序列化還原物件
Dim ser As New XmlSerializer(GetType(MyProduct))
dim fs as New FileStream(application.StartupPath & "\MyProduct.xml",FileMode.Open)
Dim obj As MyProduct = CType(ser.Deserialize(fs), MyProduct)
fs.Close()

MessageBox.Show("Deseriablize OK...PublicBookName = " & obj.productName)
End Sub
End Class
========================================
使用控制Array型別序列化
Imports System.Xml.Serialization

Public Class MyProduct
Public productID As Integer
Public productName As String
End Class

=====================

Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
'1、建立及使用物件
Dim obj As New Group
Dim emp1 As New Employee
Dim emp2 As New Employee
emp1.Name = "Jerry"
emp2.Name = "John"

obj.Employees(0) = emp1
obj.Employees(1) = emp2
'2、序列化XML物件
Dim ser As New XmlSerializer(GetType(Group))
Dim fs As New FileStream(Application.StartupPath & "\Group.xml", FileMode.Create)
ser.Serialize(fs, CType(obj, Group))
fs.Close()
End Sub

Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
'3、反序列化還原物件
Dim ser As New XmlSerializer(GetType(Group))
Dim fs As New FileStream(Application.StartupPath & "\Group.xml", FileMode.Open)

Dim obj As Group = CType(ser.Deserialize(fs), Group)
fs.Close()
MessageBox.Show("Deseriablize OK...Group = " & obj.Employees(0).Name)

End Sub

2009年8月31日 星期一

多執行緒中共用資源(M06)

多執行緒中共用資源
1、多執行緒中的共用資源必須要被保護
a、避免導致程式運算錯誤
=>多執行緒的執行環境中,執行緒輪流使用虎理器的資源做運算,當然也輪流休息。如果A執行緒休息的時間,有其他的執行緒修改A執行緒所使用的物件狀態;等A執行緒下次執行,就會產生錯誤的結果。
=>因此在多執行緒中,我們使用一些機制,保護多執行緒中共資源的狀態,這就稱之為同步化(Synchronization)

2、保護共用資源方式
a、Synchronization Lock
b、Monitor
c、Mutex
d、Semaphore
e、ReaderWriterLock
f、Interlocked
========================
Synchronization Lock(最常用)
1、確保程式碼區塊執行到完畢,不受其它執行緒打斷
a、C#:使用lock程式碼區塊
b、VB:使用SyncLock程式碼區塊
2、在方法宣告時使用Methodlmpl標籤
a、設定MethodlmplOptions.Synchronized
b、鎖定範圍為整個方法

=>保護共用資源的最簡單的方法,就是直接鎖定程式,讓程式只有一個執行緒執行,稱之為同步化鎖定(Synchronization Lock)。
=>使用時注意:鎖定愈短愈好,避免Thread排隊,多資源利用避免DeadLock

2009年8月26日 星期三

多執行緒應用程式(M06)

多執行緒應用程式

一、執行緒的基本觀念
1、虛擬的執行單元
2、可以讓程式同時進行多項工作
3、減少系統資源的浪費
4、共用資源的鎖定(Synchronization)

一般在應用程式開啟時,執行環境會自動建立一個執行緒執行程式中的功能,稱之為主執行緒(Main thread)。
每一個程式中的執行緒都是一個虛擬的執行單元,建立之後就會在程式的背景執行交付的工作。

優點
像是程式在開啟網路資源或是開啟資料連結的時候都會有一些等待的時間,多執行最大的好處利用這一些空閒時間執行其它的工作,增加系統資源的使用效率。

缺點
把程式變複雜,不容易除錯
多執行緒應用程式中需要處理共用資源鎖定(synchronization),以及避免程式死結(deadlock)
==========================
二、建立沒有回傳值、沒有參數列的執行緒
1、System.Threading命名空間
2、沒有回傳值、沒有參數列
3、建立執行緒步驟
a、建立執行緒所要呼叫的方法
b、將方式記錄在ThreadStart Delegate實體
c、建立Thread物件實體,傳入ThreadStart Delegate
d、呼叫Thread物件的Start方法,啟動執行緒
Imports System.Threading

Module Module1
Sub Main()
Console.WriteLine("MainThread:Application Start.")
Dim ts As New ThreadStart(AddressOf Work)
Dim worker As Thread = New Thread(ts)

'當背景程式時,主程式執行完,背景程式如未執行完,會直接結束,不會有結果產生
'worker.IsBackground = True

worker.Start()
Console.WriteLine("MainThread:Application End.")

End Sub
Private Sub Work()
'Thread.Sleep(1000)
Console.WriteLine("Thread{0}:" & DateTime.Now.ToLongTimeString())
End Sub
End Module
==========================
三、Thread物件常用成員
1、常用屬性
Name:取得或設定執行緒名稱
Priority:取得或設定執行緒的優先權
ThreadState:取得目前的執行緒狀態
2、常用方法
Join:將執行緒插入目前工作中
Thread.Sleep靜態方法:中止執行緒一段時間再執行

==========================
四、執行緒的生命週期



程式中建立的執行緒,實際由OS的環境執行。

一般機器只有一個CPU,因此雖可以建立多個執行緒,但不能同時執行,由系統排程之後決定先後執行順序,一般由優先權高的執行緒會先被執行。

Windows OS具有分時多工特性,因此執行緒管理較為簡單,當程式呼叫Thread物件方法就可以改變執行緒狀態。

下面是執行生命週期主要的狀態
1、Unstarted:當Thread物件被建立,但是並未進入執行狀態時,即為Unstarted狀態。

2、Running:
a、當Thread物件的start方法之後,執行緒被執行時,就進入Running狀態。
b、當Thread由WaitSleepJoin狀態或是呼叫ResetAbort方法恢復執行時,就進入Running狀態。

3、WaitSleepJoin:當程式呼叫Thread物件的Join方法、Sleep靜態方法或是Monitor.Wait方法時,都會進入WaitSleepJoin狀態,必須等到暫停的原因解除後,才會恢復執行。

4、AbortRequested:當程式呼叫Thread物件的Abort方法,執行緒就會進入AbortRequested狀態。如果沒有呼叫ResetAbort方法,則執行緒就會停止執行(Abort)。

=>執行緒的生命週期狀態,可以透過Thread物件的ThreadState屬性來取得。
=>通常執行緒狀態只與偵錯有關,不適宜使用來同步處理執行緒的活動。

==========================
五、ParameterizedThreadStart Delegate
1、ThreadStart無法代入資料到執行緒執行
改用ParameterizedThreadStart Delegate
=>.NET Framework 2.0中,增加ParameterizedThreadStart Delegate定義
2、規格
(1)沒有回傳值
(2)接收Object型別參數
3、呼叫Thread物件的Start方法時代入參數執行
Imports System.Threading

Module Module1

Private Sub Work(ByVal name As Object)
Console.WriteLine("Work with Parameter:" + name)
End Sub
Sub Main()
Dim doSomething As New ParameterizedThreadStart(AddressOf Work)
Dim worker As Thread = New Thread(doSomething)
worker.Start("John")
End Sub

End Module
==========================
六、中止執行緒執行
1、呼叫Thread物件的Abort方法
a、觸發ThreadAbortException
b、可能危及應用程式定義域中(AppDomain)的其它工作
=>當Abort方法被呼叫時,執行環境會產生ThreadAbortException,除非使用Thread.ResetAbort方法解除Abort狀態,不要執行緒會中止執行

2、建立CriticalRegion
a、使用BeginCriticalRegion及EndCriticalRegion建立關鍵區域
b、避免執行緒停止時導致的不穩定情況發生
=>.NET Framework2.0的執行緒架構中才有

Imports System.Threading
Module P12_2_StoppingThreads
Sub AbortThisThread()
Thread.BeginCriticalRegion()
Console.WriteLine("BeginCriticalRegion")
For i As Integer = 0 To 1000
Console.Write("O")
Next
Console.WriteLine("EndCriticalRegion")
Thread.EndCriticalRegion()
For i As Integer = 0 To 1000
Console.Write("1")
Next
End Sub

Sub main()
Dim newThread As New Thread(New ThreadStart(AddressOf AbortThisThread))
newThread.Start()
Thread.Sleep(1)
Console.WriteLine("abort")
newThread.Abort()
Console.WriteLine("end")
End Sub
End Module

==========================
七、執行緒執行環境(Execution Context)
1、當執行緒被建立時,預設會套用既有執行緒背景環境設定
a、安全性資訊
b、區域語系資訊
c、交易環境資訊
=>當程式建立新執行緒時,有執行緒的Execution Context的設定,像是安全性資訊、區域語系資訊及交易環境的資訊,都會傳遞到新執行緒中套用

2、ExecutionContext物件類別
a、常用方法
(1)SuppressFlow(static method):呼叫此方法可暫停將執行環境的設定傳遞給新的執行緒使用
(2)RestoreFlow(static method):呼叫此方法可恢復繼續執行環境的設定傳遞
(3)Capture(static method):複製目前執行緒的執行環境
(4)Run(static method):可以將程式執行在指定的執行環境中
(5)Undo:呼叫此方法可恢復繼續執行環境的設定傳遞
==========================
八、ThreadPool
1、更有效率的建立執行緒方式
a、系統會自動根據處理器的狀況做最佳化
b、可快速取得多個背景執行緒
=>許多應用程式建立的執行緒把很多時間花費在休眠狀態,等待事件發生;也有的執者進入休眠狀態後只負責定時甦醒,來輪詢變更更新狀態的資訊。
=>ThreadPool可將執行完的執行緒先暫存在集區中,下次程式需要執行緒執行工作時,就可以直接從集區中重覆使用執行緒,節省建立新執行緒所需要消眊的系統資源。

2、不適合情境
a、需要為個別執行緒設定優先權
b、需要為個別執行緒建立identity,讓後緒程式可以使用
c、執行長時間工作
d、用於single-threaded apartment應用程式環境中
=>因執行緒是由集區取出來使用的,因此程式對於該執行緒無法做太多設定,因而不適用在這些狀況
Module Module1
Sub Work(ByVal o As Object)
Console.WriteLine("Work with Parameter:")
End Sub

Sub Main()
Dim WCB As New WaitCallback(AddressOf Work)
If System.Threading.ThreadPool.QueueUserWorkItem(WCB) Then
Console.WriteLine("OK")
End If

End Sub
End Module
==========================
九、Timer物件類別
1、來源
a、System.Form.Form
b、System.threading=>CallBack,會以另一各Thread執行
c、System.Timers=> 事件,會以另一各Thread執行
2、用於定期觸發某特定方法執行
a、Threading.TimerCallback delegate
b、Change方法:用於調整觸發方法的間隔
c、Dispose方法:釋放Timer物件執行時所參考的外部資源
=>Timer可定間隔一段時間觸發某方法,透過Timer觸發方法參考必須要先記錄到TimerCallback Delegate物件之後,再傳到Timer物件中執行

Imports System.Threading

Module Module1

Sub Main()
Dim T1 As New Threading.Timer(New TimerCallback(AddressOf Time), Nothing, 0, 2000)
Console.Read()
End Sub
Sub Time(ByVal o As Object)
Console.WriteLine("Time:" & Date.Now)
End Sub
End Module

2009年8月24日 星期一

建立Windows Service(M07)

認識Windows服務(Service)

  • 作業系統的常駐程式
=>默默在背景執行的程式
=>電腦啟動時自動啟動
  • 例如
透過網路存取別人電腦資料時。
1、Server:提供透過網路存取服務(提供資源)
2、Workstation:提供與遠端使用者連線的用戶端服務(要求存取資源)
=>Windows服務是系統的常駐程式,在系統開機之後,不需經由使用者登入及啟動,服務就會自動啟動,並且在背景默默的執行服務程式。
=>Windows Service專案也是建置為.exe檔,但此程式並不能直接執行,而是必須先安裝到服務管理員啟動

=>Service類別屬性
  • 決定服務是否可啟用、停止、暫停與繼續
  • CanStop:預設為True
  • CanPauseAndContinue:預設為False
  • CanShutdown:預設為False
  • AutoLog:預設為True
=>Service類別事件
  • OnStart:啟用服務會執行的程式
  • OnStop:停用服務會執行的程式
程式實作
1、建立Windows Service的專案步驟如下:
a、File-->New Project-->Project types:選取Windows,在Templates:選取Windows Service

b、改寫Service類別的OnStart與OnStop程序
Imports System.IO

Public Class Service1
Dim WithEvents serviceTimer As System.Timers.Timer

Public Sub New()

' 此為 Windows Form 設計工具所需的呼叫。
InitializeComponent()

' 在 InitializeComponent() 呼叫之後加入任何初始設定。
serviceTimer = New System.Timers.Timer
serviceTimer.Interval = 60000
End Sub

Protected Overrides Sub OnStart(ByVal args() As String)
serviceTimer.Start()

End Sub

Protected Overrides Sub OnStop()
serviceTimer.Stop()

End Sub

Private Sub serviceTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles serviceTimer.Elapsed
Dim cDrive As New driveinfo("C:\")
eventlog.WriteEntry("目前磁碟的剩餘空間:" & cdrive.TotalFreeSpace)
End Sub
End Class

c、加入安裝程式,並設定安裝屬性
d、建置專案
e、安裝服務
(1)使用InstallUtil.exe(適用於開發測試)
VS2005-->VS TOOL-->命令執行工具

安裝
InstallUtil 服務.exe
移除
InstallUtil 服務.exe -u
ps:將服務.exe直接拉至命令提示列就會自動帶出路徑

(2)使用安裝專案
f、從「服務管理員」啟動服務

服務管理員(SCM:Service Control Manager)(M07)

SCM:Service Control Manager

1、路徑
a、我的電腦-->管理-->服務(Window XP)
b、開始-->系統管理工具-->服務

2、啟動類型
a、自動(Automatic):服務在開機後自動啟動
b、手動(Manual):服務必須經由人為或程式啟動才會執行
c、停用(Disabled):服務不可啟動

3、狀態
a、啟動(Start):服務正在執行中
b、停止(Stop):服務尚未執行
c、暫停(Pause):服務執行中進入中止狀態
d、繼續(Resume):將中止狀態服務為繼續執行