(7)C#里的线程和流
?
C#支持通過多線程并行地執行代碼,一個線程有它獨立的執行路徑,能夠與其它的線程同時地運行。一個C#程序開始于一個單線程,這個單線程是被CLR和操作系統(也稱為“主線程”)自動創建的,并具有多線程創建額外的線程。這里的一個簡單的例子及其輸出:
? 調用Start方法后,線程開始運行,線程一直到它所調用的方法返回后結束。
?
命名線程
? 線程可以通過它的Name屬性進行命名,這非產有利于調試:可以用Console.WriteLine打印出線程的名字,Microsoft Visual Studio可以將線程的名字顯示在調試工具欄的位置上。線程的名字可以在被任何時間設置——但只能設置一次,重命名會引發異常。
? 程序的主線程也可以被命名,下面例子里主線程通過CurrentThread命名:
沒想到看不見的線程可以通過名字來區分,真是太可愛了。。
?
為了強化大家對線程的理解,再附上一個例子:
該示例創建一個名為 Worker 的類,該類包含輔助線程將執行的方法 DoWork。這實際上是輔助線程的 Main 函數。輔助線程將通過調用此方法來開始執行,并在此方法返回時自動終止。既然線程如此強大,為什么不多整幾個呢?這里又引出了另一個問題。。。
何時使用多線程
??? 多線程程序一般被用來在后臺執行耗時的任務。主線程保持運行,并且工作線程做它的后臺工作。對于Windows Forms程序來說,如果主線程試圖執行冗長的操作,鍵盤和鼠標的操作會變的遲鈍,程序也會失去響應。由于這個原因,應該在工作線程中運行一個耗時任務時 添加一個工作線程,即使在主線程上有一個有好的提示“處理中...”,以防止工作無法繼續。這就避免了程序出現由操作系統提示的“沒有相應”,來誘使用戶 強制結束程序的進程而導致錯誤。模式對話框還允許實現“取消”功能,允許繼續接收事件,而實際的任務已被工作線程完成。BackgroundWorker恰好可以輔助完成這一功能。
? 何時不要使用多線程
??? 多線程也同樣會帶來缺點,最大的問題是它使程序變的過于復雜,擁有多線程本身并不復雜,復雜是的線程的交互作用,這帶來了無論是否交互是否是有意的,都會 帶來較長的開發周期,以及帶來間歇性和非重復性的bugs。因此,要么多線程的交互設計簡單一些,要么就根本不使用多線程。除非你有強烈的重寫和調試欲 望。當用戶頻繁地分配和切換線程時,多線程會帶來增加資源和CPU的開銷。
多線程的應用十分廣泛,但是有利有弊,大家編程的時候注意平衡就好。
?
?
下面講下自己學習“流”的一些心得,在我看來,C#的數據傳輸都是靠流來實現,數據隨著涓涓細流流向他們該去的地方,精確無誤,十分高效。特別是文件的傳輸,萬萬離不開流。
MemoryStream類用于向內存而不是磁盤讀寫數據。MemoryStream封裝以無符號字節數組形式存儲的數據,該數組在創建 MemoryStream對象時被初始化,或者該數組可創建為空數組??稍趦却嬷兄苯釉L問這些封裝的數據。內存流可降低應用程序中對臨時緩沖區和臨時文件 的需要。
memoryStream的使用實例:
using System; ?
using System.IO; ?
using System.Text; ?
class program{ ?
static void Main() ?
{ ?
int count; ?
byte[] byteArray; ?
char[] charArray; ?
UnicodeEncoding uniEncoding=new UnicodeEncoding(); ?
byte[] firstString=uniEncoding.GetBytes("努力學習"); ?
byte[] secondString=uniEncoding.GetBytes("不做C#中的菜鳥"); ?
using (MemoryStream memStream=new MemoryStream(100)) ?
{ ?
memStream.Write(firstString,0,firstString.Length); ?
count=0; ?
while(count<secondString.Length) ?
{ ?
memStream.WriteByte(secondString[count++]); ?
} ?
Console.WriteLine("Capacity={0},Length={1},Position={2}\n",memStream.Capacity.ToString(),memStream.Length.ToString(),memStream.Position.ToString()); ?
memStream.Seek(0, SeekOrigin.Begin); ?
byteArray=new byte[memStream.Length]; ?
count=memStream.Read(byteArray,0,20); ?
while(count<memStream.Length) ?
{ ?
byteArray[count++]=Convert.ToByte(memStream.ReadByte()); ?
} ?
charArray=new char[uniEncoding.GetCharCount(byteArray,0,count)]; ?
uniEncoding.GetDecoder().GetChars(byteArray,0,count,charArray,0); ?
Console.WriteLine(charArray); ?
Console.ReadKey(); ?
} ?
} ?
}
關于文件流的寫入與讀出,這里提供給讀者兩個代碼片段:
文件流寫入:
?private void btnChooseOpenFile_Click(object sender, EventArgs e)
??????? {
??????????? //選擇文本框 對象
??????????? OpenFileDialog ofd = new OpenFileDialog();
??????????? ofd.InitialDirectory = @"C:\Users\John\Desktop";
??????????? //如果用戶確定
??????????? if (ofd.ShowDialog() == DialogResult.OK)
??????????? {
??????????????? //將用戶選擇的文件路徑顯示在文本框上
??????????????? txtFilePathOpen.Text = ofd.FileName;
??????????? }
??????? }
??????? //保存文件
??????? private void btnSave_Click(object sender, EventArgs e)
??????? {
??????????? string strContent = txtInputSave.Text.Trim();
??????????? //創建文件流(文件路徑,文件操作、創建)
??????????? using (FileStream fs = new FileStream(txtFilePathOpen.Text, FileMode.Create))
??????????? {
??????????????? //將字符串字符串轉成byte數組
??????????????? byte[] byteFile = Encoding.UTF8.GetBytes(strContent);
??????????????? //參數:要寫到文件的數據數組,從第幾個開始寫,一共寫多少個
??????????????? fs.Write(byteFile, 0, byteFile.Length);
??????????????? MessageBox.Show("保存成功!");
??????????? }
??????? }
文件流讀出:
private void btnChooseOpenFile2_Click(object sender, EventArgs e)
??????? {
??????????? //選擇文本框 對象
??????????? OpenFileDialog ofd = new OpenFileDialog();
??????????? ofd.InitialDirectory = @"C:\Users\John\Desktop";
??????????? //如果用戶確定
??????????? if (ofd.ShowDialog() == DialogResult.OK)
??????????? {
??????????????? //將用戶選擇的文件路徑顯示在文本框上
??????????????? txtFilePathOpen2.Text = ofd.FileName;
??????????? }
??????? }
??????? private void btnRead_Click(object sender, EventArgs e)
??????? {
??????????? using (FileStream fs = new FileStream(txtFilePathOpen2.Text, FileMode.Open))
??????????? {
??????????????? byte[] byteData = new byte[1024 * 1024 * 4];
??????????????? //返回讀取的長度
??????????????? int length=fs.Read(byteData,0,byteData.Length);
??????????????? if (length > 0)
??????????????? {
??????????????????? string strData = Encoding.UTF8.GetString(byteData);
??????????????????? txtOutputRead.Text = strData;
??????????????????? MessageBox.Show("讀取成功");
??????????????? }
??????????? }
??????? }
目前我對流的理解止步于此,不過今后我會對這方面多加關注,如果這篇博客有什么不對的地方,還望大家指出,共同學習,一起進步。
轉載于:https://www.cnblogs.com/shenyuelong/p/4477620.html
總結
以上是生活随笔為你收集整理的(7)C#里的线程和流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抗日战争中日双方实力对比?
- 下一篇: PHP pear安装