主頁 > .NET開發 > 【Stream—4】FileStream相關知識分享

【Stream—4】FileStream相關知識分享

2020-09-22 09:00:31 .NET開發

一、如何理解FIleStream

通過前3章的學些,相信大家對于Stream已經有一定的了解,但是又如何去理解FileStream呢?請看下圖:

 

 我們磁盤中的任何檔案都是通過二進制陣列組成,最為直觀的就是記事本了,當我們新建一個記事本時,它的大小時0KB,我們每次輸入一個數字或字母時,檔案便會自動增大到4KB,可見,隨著我們輸入的內容越來越多,檔案也會越來越大,同理,當我們洗掉檔案內容時,檔案也會相應的減小,對了,聰明的你肯定會問:誰將內容以怎樣的形式放到檔案中去了?

好問題,還記得第一章流的概念嘛?對了,真實世界的一群魚可以通過河流往前往各個地方,FileStream也一樣,byte可以通過FileStream進行傳輸,這樣我們便能在計算機上對任何檔案進行一系列操作了,

二、FileStream的重要性

FileStream顧名思義檔案流,我們電腦上的檔案都可以通過檔案流進行操作,例如檔案的復制、簡介、粘貼、洗掉、本地檔案上傳、下載、等許多重要的功能都離不開檔案流,所以檔案流不僅在本機上非常重要,在如今的網路世界上也萬萬不能缺少的,想象一下我們開啟虛擬機后,直接從本地復制一個檔案到虛擬機上,時多么的方便,如果沒有檔案流,這個將難以想象,(大家別誤解,檔案流通過網路流將客戶都安上傳的檔案傳到服務器端接收,然后通過檔案流進行處理,下載正好相反)

三、FileStream常用建構式介紹

1、FileStream(SafeFileHandle safeFileHandle,FileAccess fileAccess)

非托管引數SafeFileHandle簡單介紹

SafeFileHandle:是一個檔案安全句柄,這樣的解釋可能大家一頭霧水,別急,大家先不要去理睬這深邃的含義,只要知道這個型別是C#非托管資源,也就是說它能夠呼叫非托管資源的方法,而且不屬于C#回識訓制,所以我們必須使用GC手動或其他方式(Finalize或Dispose方法)進行非托管資源的回收,所以SafeFileHandle是一個默默無聞的保鏢,一直暗中保護FileStream和檔案的安全,為了讓大家更好的理解這個保鏢,請看第一段代碼:

 

1         static void Main(string[] args)
2         {
3             var rootPath = Environment.CurrentDirectory;
4             var fileName = Path.Combine(rootPath, "TextFile1.txt");//@"TextFile1.txt";
5             FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
6             Console.ReadLine();
7             File.Delete(fileName);
8             Console.ReadKey();
9         }

我們運行一下,結果報錯了,我看看一下錯誤:

 

 為什么會報錯呢?其實程式被卡在了Console.ReadLine()這里,FileStream并沒有被釋放,系統不知道這個檔案是否還有用,所以幫我們保護這個檔案(那個非托管資源SafeFileHandle所使用的記憶體還被占用著)所以SafeFileHandle在內部保護了這個檔案從而報出了這個例外,如果我們將流關閉后,這個問題就不存在了,

所以,我們又回到了一個老問題上面,我們每次使用完FileStream后都必須將他關閉并釋放資源,

2、FileStream(string str,FileModel model)

string 引數表示檔案所在的地址,FileMode是個列舉,表示確定如何打開或創建檔案 ,

FileModel列舉引數包含以下內容:

成員名稱

說明

Append

打開現有檔案并查找到檔案尾,或創建新檔案,FileMode.Append 只能同 FileAccess.Write 一起使用,

    

Create

指定作業系統應創建新檔案,如果檔案已存在,它將被改寫,這要求 FileIOPermissionAccess.Write,

System.IO.FileMode.Create 等效于這樣的請求:如果檔案不存在,則使用 CreateNew;否則使用 Truncate,

CreateNew

指定作業系統應創建新檔案,此操作需要 FileIOPermissionAccess.Write,如果檔案已存在,則將引發 IOException,

    

Open

指定作業系統應打開現有檔案,打開檔案的能力取決于 FileAccess   所指定的值,如果該檔案不存在,

則引發 System.IO.FileNotFoundException,

    

OpenOrCreate

指定作業系統應打開檔案(如果檔案存在);否則,應創建新檔案,如果用 FileAccess.Read   打開檔案,則需要

 FileIOPermissionAccess.Read,如果檔案訪問為 FileAccess.Write 或 FileAccess.ReadWrite,則需要

FileIOPermissionAccess.Write,如果檔案訪問為 FileAccess.Append,則需要 FileIOPermissionAccess.Append,

    

Truncate

指定作業系統應打開現有檔案,檔案一旦打開,就將被截斷為零位元組大小,此操作需要 FileIOPermissionAccess.Write,

試圖從使用 Truncate 打開的檔案中進行讀取將導致例外,

 3、FileStream(IntPtr intPtr,FIleAccess fileAccess,Boolean ownsHandle)

FileAccess引數也是一個列舉,表示對該檔案的操作權限:

 

 引數ownsHandle:也就是類似于前面和大家介紹的SafeFileHandler,有2點必須注意:(1)對于指定的檔案句柄,作業系統不允許所請求的access,例如:當access為Write或ReadWrite而檔案句柄設定為只讀訪問的時候,會出現例外,所以ownsHandle才是老大,FileAccess的權限應該在ownsHandle的范圍內,(2)FileStream假定它的句柄有獨占控制權,當FileStream也持有句柄時,讀取、寫入或查找可能會導致資料破壞,為了資料安全,請使用句柄前呼叫Flush,并避免在使用完句柄后呼叫Close以外的任何方法,

4、FileStream(string str,FileModel model,FileAccess,fileAccess,FileShare fileShare)

FileShare:同樣時一個列舉型別,確定檔案如何由行程共享,

Delete

允許隨后洗掉檔案,

Inheritable

使檔案句柄可由子行程繼承,Win32 不直接支持此功能,

None

謝絕共享當前檔案,檔案關閉前,打開該檔案的任何請求(由此行程或另一行程發出的請求)都將失敗,

Read

允許隨后打開檔案讀取,如果未指定此標志,則檔案關閉前,任何打開該檔案以進行讀取的請求(由此行程或另一行程發出的請求)都將失敗,但是,即使指定了此標志,仍可能需要附加權限才能夠訪問該檔案,

ReadWrite

允許隨后打開檔案讀取或寫入,如果未指定此標志,則檔案關閉前,任何打開該檔案以進行讀取或寫入的請求(由此行程或另一行程發出)都將失敗,但是,即使指定了此標志,仍可能需要附加權限才能夠訪問該檔案,

Write

允許隨后打開檔案寫入,如果未指定此標志,則檔案關閉前,任何打開該檔案以進行寫入的請求(由此行程或另一程序序發出的請求)都將失敗,但是,即使指定了此標志,仍可能需要附加權限才能夠訪問該檔案,

5、FileStream(string str,FileMode mode,FileAccess fileAccess,FileShare fileShare,Int32 i,Boolean async)

Int32:這是一個緩沖區的大小,大家可以按照自己的需要定制;

Boolean async:是否異步讀寫,告訴FileStream示例,是否采用異步讀寫

6、FileStream(string str,FileMode mode,FileShare fileShare,Int32 i,FileOption fileOption)

FileOption:這是類似于FileStream對于我呢見操作的高級選項

四、FileStream常用屬性介紹

1、CanRead:指示FileStream是否可以讀操作

2、CanSeek:指示FileStream是否可以跟蹤查找流操作

3、IsAsync:FileStream是否同步作業還是異步作業

4、Name:FileStream的名字,只讀屬性

5、ReadTimeout:設定讀取超時時間

6、SafeFileHandle:檔案安全句柄,只讀屬性

7、Position:當前FileStream所在的流的位置

五、FileStream常用方法介紹

以下方法重寫了Stream的一些虛方法

1、IAsyncResult BeginRead 異步讀取

2、IAsyncResult BeginWrite 異步寫

3、void Close 關閉當前FileStream

4、void EndRead 異步讀取結束

5、void EndWrite 異步寫結束

6、void Flush 立刻釋放緩沖區,將資料全部匯出到基礎流(檔案)中

7、int Read 一般讀取

8、int ReadByte 讀取單個位元組

9、long Seek 跟蹤查找流所在的位置

10、void SetLength 設定FileStream的長度

11、void Write 一般寫

12、void WriteByte 寫入單個位元組

六、屬于FileStream獨有的方法

1、FileSecurity GetAccessControl()

這個不是很常用,FileSecurity時檔案安全類,直接表達當前檔案的訪問控制串列(ACL)的復合當前檔案權限的專案,ACL大家有個了解就行,以后會單獨和大家討論下ACL方面的知識

2、void Lock(long position,long length)

這個Lock方法和執行緒中的Lock關鍵字很不一樣,它能夠鎖住檔案中的某一部分,非常的強悍!用了這個方法我們能夠精確鎖定住我們要鎖住的檔案的部分內容

3、void SetAccessControl(FileSecurity fileSecurity)

和GetAccessControl很相似,ACL技識訓再以后單獨介紹

4、void Unlock(long position,long length)

正好和lock方法相反,對于檔案部分的解鎖

七、檔案的新建和拷貝(主要演示檔案同步和異步操作)

首先我們嘗試DIY一個IFileCOnfig

 

1     public interface IFileConfig
2     {
3         string FileName { get; set; }
4         bool IsAsync { get; set; }
5     }

 創建檔案配置類CreateFileConfig,用于添加檔案一些配置設定,實作添加檔案的操作

 1     public class CreateFileConfig : IFileConfig
 2     {
 3         /// <summary>
 4         /// 檔案名稱
 5         /// </summary>
 6         public string FileName { get; set; }
 7         /// <summary>
 8         /// 是否異步
 9         /// </summary>
10         public bool IsAsync { get; set; }
11         /// <summary>
12         /// 創建檔案所在Url
13         /// </summary>
14         public string CreateUrl { get; set; }
15     }

讓我們定義一個檔案流測驗類:FileStreamTest來實作檔案的操作,

1     /// <summary>
2     /// 檔案測驗類
3     /// </summary>
4     public class FileStreamTest

在該類中實作一個簡單的Create方法,用來同步或異步的實作添加檔案,FileStream會根據配置類去選擇相應的建構式,實作異步或同步的添加方式

 1         /// <summary>
 2         /// 添加檔案方法
 3         /// </summary>
 4         /// <param name="config"></param>
 5         public void Create(IFileConfig config)
 6         {
 7             lock (_lockObject)
 8             {
 9                 //得到創建檔案配置的物件
10                 var createFileConfig = config as CreateFileConfig;
11                 //假設創建完檔案后寫入一段話,實際專案中無需這么做,這里只是演示
12                 char[] insertContent = "HellowWord".ToCharArray();
13                 if (createFileConfig == null)
14                 {
15                     return;
16                 }
17                 //轉化成byte[]
18                 byte[] byteArrayContent = Encoding.Default.GetBytes(insertContent, 0, insertContent.Length);
19                 //根據傳入的組態檔來決定是否同步或者異步實體化Stream物件
20                 FileStream stream = createFileConfig.IsAsync
21                     ? new FileStream(createFileConfig.CreateUrl, FileMode.Create, FileAccess.ReadWrite, FileShare.None,
22                         4096, true)
23                     : new FileStream(createFileConfig.CreateUrl, FileMode.Create);
24                 using (stream)
25                 {
26                     //如果不注釋下面代碼會拋出例外,google上提示是WriteTimeOut只支持網路流
27                     //stream.WriteTimeout=READ_OR_WRITE_TIMEOUT;
28                     //如果流是同步并且可寫
29                     if (!stream.IsAsync && stream.CanWrite)
30                     {
31                         stream.Write(byteArrayContent, 0, byteArrayContent.Length);
32                     }
33                     else if (stream.CanWrite)//異步可寫
34                     {
35                         stream.BeginWrite(byteArrayContent, 0, byteArrayContent.Length, End_CreateFileCallBack, stream);
36                     }
37                 }
38             }
39         }

如果采用異步的方式則最后會進入End_CreateFileCallBack回呼方法,result AsyncState 物件就是上圖stream.BeginWrite()方法的最后一個引數,還有一點必須注意的是每一次使用BeginWrite()方法都要帶上EndWrite()方法,Read方法也一樣

 1         /// <summary>
 2         /// 異步寫檔案callBack方法
 3         /// </summary>
 4         /// <param name="result"></param>
 5         private void End_CreateFileCallBack(IAsyncResult result)
 6         {
 7             //從IAsyncResult物件中得到原來的FileStream
 8             var stream = result.AsyncState as FileStream;
 9             //結束異步寫
10             if (stream != null)
11             {
12                 Console.WriteLine("異步創建檔案地址{0}", stream.Name);
13                 stream.EndWrite(result);
14             }
15 
16             Console.ReadKey();
17         }

檔案復制的方式思路比較相似,首先定義復制檔案配置類,由于在異步回呼中用到該配置類的屬性,所以新增了檔案流物件和相應的位元組陣列

 1         /// <summary>
 2         /// 異步讀檔案方法
 3         /// </summary>
 4         /// <param name="result"></param>
 5         private void End_ReadFileCallBack(IAsyncResult result)
 6         {
 7             //得到先前的組態檔
 8             var config = result.AsyncState as CopyFileConfig;
 9             //結束異步讀
10             config?.OriginalFileStream.EndRead(result);
11             //異步讀后立即寫入新檔案地址
12             if (config != null)
13             {
14                 FileStream copyStream = new FileStream(config.DestinationFileUrl, FileMode.CreateNew, FileAccess.Write, FileShare.Write, 4096, true);
15                 using (copyStream)
16                 {
17                     Console.WriteLine("異步復制原檔案地址:{0}", config.OriginalFileStream.Name);
18                     Console.WriteLine("復制后的新檔案地址:{0}", config.DestinationFileUrl);
19                     //呼叫異步寫方法callBack方法為End_CreateFileCallBack,引數是copyStream
20                     copyStream.BeginWrite(config.OriginalFileBytes, 0, config.OriginalFileBytes.Length,
21                         End_CreateFileCallBack, copyStream);
22                 }
23             }
24         }

然后在FileStreamTest類中新增一個Copy方法實作檔案的復制功能

 1         /// <summary>
 2         /// 復制檔案
 3         /// </summary>
 4         /// <param name="config"></param>
 5         public void Copy(IFileConfig config)
 6         {
 7             lock (_lockObject)
 8             {
 9                 //得到CopyFileConfig物件
10                 var copyFileConfig = config as CopyFileConfig;
11                 if (copyFileConfig == null)
12                 {
13                     return;
14                 }
15                 //創建同步或異步流
16                 FileStream stream = copyFileConfig.IsAsync
17                     ? new FileStream(copyFileConfig.OriginalFileUrl, FileMode.Open, FileAccess.Read, FileShare.Read,
18                         4096, true)
19                     : new FileStream(copyFileConfig.OriginalFileUrl, FileMode.Open);
20                 //定義一個byte陣列接收從原檔案讀取的byte資料
21                 byte[] originalFileBytes = new byte[stream.Length];
22                 using (stream)
23                 {
24                     //如果異步流
25                     if (stream.IsAsync)
26                     {
27                         //將該流和流獨處的byte[]資料放入配置類,在callback中可以使用
28                         copyFileConfig.OriginalFileStream = stream;
29                         copyFileConfig.OriginalFileBytes = originalFileBytes;
30                         if (stream.CanRead)
31                         {
32                             //異步開始讀取,讀取完后進入End_ReadFileCallBack方法,該方法接收copyFileConfig引數
33                             stream.BeginRead(originalFileBytes, 0, originalFileBytes.Length, End_ReadFileCallBack,
34                                 copyFileConfig);
35                         }
36                         else//否則同步讀取
37                         {
38                             if (stream.CanRead)
39                             {
40                                 //讀取原檔案
41                                 stream.Read(originalFileBytes, 0, originalFileBytes.Length);
42                             }
43                             //定義一個寫流,在新位置中創建一個檔案
44                             FileStream copyStream = new FileStream(copyFileConfig.DestinationFileUrl, FileMode.CreateNew);
45                             using (copyStream)
46                             {
47                                 //將原檔案的內容寫進新檔案
48                                 copyStream.Write(originalFileBytes, 0, originalFileBytes.Length);
49                             }
50                         }
51 
52                         Console.ReadLine();
53                     }
54                 }
55             }
56         }

最后,如果采用異步的方式,則會進入End_ReadFileCallBack回呼函式進行異步讀取和異步寫操作

 1         /// <summary>
 2         /// 異步讀檔案方法
 3         /// </summary>
 4         /// <param name="result"></param>
 5         private void End_ReadFileCallBack(IAsyncResult result)
 6         {
 7             //得到先前的組態檔
 8             var config = result.AsyncState as CopyFileConfig;
 9             //結束異步讀
10             config?.OriginalFileStream.EndRead(result);
11             //異步讀后立即寫入新檔案地址
12             if (config != null)
13             {
14                 FileStream copyStream = new FileStream(config.DestinationFileUrl, FileMode.CreateNew, FileAccess.Write, FileShare.Write, 4096, true);
15                 using (copyStream)
16                 {
17                     Console.WriteLine("異步復制原檔案地址:{0}", config.OriginalFileStream.Name);
18                     Console.WriteLine("復制后的新檔案地址:{0}", config.DestinationFileUrl);
19                     //呼叫異步寫方法callBack方法為End_CreateFileCallBack,引數是copyStream
20                     copyStream.BeginWrite(config.OriginalFileBytes, 0, config.OriginalFileBytes.Length,
21                         End_CreateFileCallBack, copyStream);
22                 }
23             }
24         }

最有讓我們在Main函式呼叫一下:

 1         static void Main(string[] args)
 2         {
 3             //檔案操作測驗
 4             FileStreamTest test = new FileStreamTest();
 5             //創建檔案配置類
 6             CreateFileConfig createFileConfig = new CreateFileConfig
 7             {
 8                 CreateUrl = @"E:\自己的\MyTest\Word\新建的.txt",
 9                 IsAsync = true
10             };
11             //復制檔案配置類
12             CopyFileConfig copyFileConfig = new CopyFileConfig
13             {
14                 OriginalFileUrl = @"E:\自己的\MyTest\Word\TextFile1.txt",
15                 DestinationFileUrl = @"E:\自己的\MyTest\Word\TextFile1-副本.txt",
16                 IsAsync = true
17             };
18             //test.Create(createFileConfig);
19             test.Copy(copyFileConfig);
20             Console.ReadKey();
21         }

輸出結果:

 

 好了,FileStream的相關知識就分享到這里了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/103495.html

標籤:C#

上一篇:百度Sitemap生成器

下一篇:C# .NET的BinaryFormatter、protobuf-net、Newtonsoft.Json以及自己寫的序列化方法序列化效率和序列化后的檔案體積大小對比

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more