net編程模式
㈠ 什麼是.net編程
.Net是一種編程框架,它提供了一個高層次的抽象,使開發人員能夠在掌握一定基礎編程知識的情況下,更容易地開發產品。.Net框架是用於開發應用軟體和託管類庫的平台,它包含了編譯器和工具,支持在生成、調試及執行託管應用程序時所需的功能。
在.NET框架中,應用程序被稱為「託管」,這意味著它們的執行是由.NET框架管理的,提供了如應用程序載入、內存管理、安全性和資源完整性等服務。.Net框架通過提供一個受控的運行時環境來管理這些執行過程,確保應用程序在運行時能夠正常工作。
在.NET框架出現之前,如C++和VB6等編程語言所處的環境中,操作系統中沒有提供類似.NET框架的服務,應用程序需要自行管理內存和安全性等,這可能導致錯誤代碼、安全漏洞以及數據丟失等問題。
.Net框架提供了豐富的工具,包括編譯器、調試器、多種編程語言、執行引擎(即Common Language Runtime, CLR)、開發工具及大量的預定義類庫(Framework Class Libraries, FCLs)。FCLs提供了廣泛的功能模塊,可以滿足開發人員的不同需求。
此外,.Net支持多種編程語言,包括VB.NET、J#、C#、F#等,所有編程語言最終都將由CLR執行,因此.Net是「語言無關」的。現在,微軟還推出了支持託管.Net編程的VC++版本。
憑借.Net框架的強大功能,.Net編程可以應用於多種場景,如桌面應用程序、Web應用程序、便攜設備應用程序、游戲開發、用戶界面開發、富互聯網開發等。通過安裝一些插件,還可以在Linux等操作系統上運行.Net程序。
㈡ 如何正確理解.NET 4.5和C#5.0中的async/await非同步編程模式
相對於之前Begin/End模式和事件模式,async/await模式讓程序員得以用同步的代碼結構進行非同步編程。async/await入門很方便,但是深入理解卻涉及很多領域,如線程池、同步上下文等等。我斷斷續續接觸了幾個月,稍微有一些心得:
await的作用是等待非同步Task完成,並不是阻塞的。舉個例子,一個非同步方法:
publicasyncTaskCaller()
{
Action0();
awaitMethod();
Action3();
}
publicasyncTaskMethod()
{
Action1();
awaitTask.Delay(1000);
Action2();
}
A.當你在非UI線程A上執行Caller(),將完成以下幾件事:
[線程A]執行Action0()
[線程A]調用await Method()
[線程A]執行Action1()
[線程A]啟動任務Task.Delay(1000),並在線程池裡安插一個新任務,在Task.Delay(1000)完成後,由另一個線程執行6
[線程A]去處理別的事情
[線程B]執行Action2()
[線程B]await Method()返回
[線程B]執行Action3()
其中,線程A和線程B並不保證是同一個線程。如果你在await前後列印線程ID,你會發現ID是不同的。
B.當你在UI線程上執行Caller(),過程有了變化:
[UI線程]執行Action0()
[UI線程]調用await Method()
[UI線程]執行Action1()
[UI線程]啟動任務Task.Delay(1000),並在線程池裡安插一個新任務,在Task.Delay(1000)完成後,由另一個線程執行6
[UI線程]去處理別的事情
[線程C]在UI線程的同步上下文中執行7(類似於在窗體類上執行Invoke()方法)
[UI線程]執行Action2()
[UI線程]await Method()返回
[UI線程]執行Action3()
可見,當使用await方法的線程為UI線程時,程序默認會通過第6步,保證await前後是同一個線程ID。這個當然是有一定性能犧牲的(甚至會造成死鎖,在D里會討論),如果你不想在await完成後回到UI線程,見C。
C. 你可以在UI線程上使用await XXX().ConfigureAwait(false)去替代awaitXXX(),來禁止當await XXX()結束時恢復線程。舉個例子,執行下列代碼是沒問題的(如B里描述的):
privateasyncvoidbutton1_Click(objectsender,EventArgse)
{
this.Text="123";
awaitTask.Delay(1000);
this.Text="321";
}
但是,執行下列代碼就會發生「線程間操作無效」的錯誤:
privateasyncvoidbutton1_Click(objectsender,EventArgse)
{
this.Text="123";
awaitTask.Delay(1000).ConfitureAwait(false);
this.Text="321";//線程間操作無效
}
因為執行
this.Text="321";
的線程已經不再是UI線程。
D. 順便一提,Task.Wait()方法,相比於await Task,會同步地執行Task。但是,如果你在UI線程上Wait的Task里本身又有await,那麼將會產生死鎖:
privatevoidFoo(objectsender,EventArgse)
{
this.Text="123";
Method().Wait();//此處發生死鎖
this.Text="321";//這行永遠也不會執行
}
privateasyncTaskMethod()
{
awaitTask.Delay(1000);
}
為什麼呢?Method().Wait()會阻塞UI線程等待Method()完成,但是參照B過程,在await完成後,Method()完成前,是需要恢復到UI線程的,但是此時UI線程已經被阻塞了,因此死鎖就發生了。
要避免這個死鎖,可以參照C。
E. 說出來你可能不信,上面的都是我手打的。在內容上雖然不一定嚴謹,但希望對樓主和其它新接觸TAP的朋友有一定啟發。