當我們在遇到需要長時間執行的任務時候,比如讀取一個文件,遠程服務調用。這些功能都會阻塞主線程,造成主線程卡死,從而造成一種軟體崩潰的假象。這樣的情況下,我們都會想到使用非同步多線程的技術去解決這個問題。 我在學習NodeJs的之前,一直以為非同步和多線程是同一個概念,當我接觸到Node的時候,感覺自己遭 ...
當我們在遇到需要長時間執行的任務時候,比如讀取一個文件,遠程服務調用。這些功能都會阻塞主線程,造成主線程卡死,從而造成一種軟體崩潰的假象。這樣的情況下,我們都會想到使用非同步多線程的技術去解決這個問題。
我在學習NodeJs的之前,一直以為非同步和多線程是同一個概念,當我接觸到Node的時候,感覺自己遭到了當頭棒喝,Node是單線程的,也不支持多線程,但是他的很多操作都是非同步的,比如文件的讀取。這讓我很沮喪,也花了很長時間去理解非同步和多線程的概念區別,現在記錄下來我現在的想法,希望看到的朋友也能幫組我理解一下。
非同步,相對於同步,C#執行代碼的順序是從上到下,從右到左,從上往下執行的這種就稱之為同步執行,非同步相對於同步,就是同時執行的意思。
如下流程圖
如上圖是同步和非同步的執行模式。
什麼是多線程?多線程是實現非同步的一種技術。綜上:非同步是一種技術功能要求,多線程是實現非同步的一種手段。除了使用多線程可以實現非同步,非同步I/O操作也能實現。硬碟,顯卡這些硬體是可以不消耗CPU資源而自動與記憶體交換數據的,這也是實現非同步的基本條件,當數據交互完成,再觸髮指定的回調函數,來實現非同步之後的同步。所以這也是NodeJs的非同步I/O操作全部是通過非同步回調來實現的原因。
在Net中可以使用委托實現非同步調用的功能。
Action test = () =>
{
for (double i = 0; i < 10000; i++)
{
Thread.Sleep(1);
}
Console.WriteLine("耗時操作結束!");
};
test.BeginInvoke(null, null);
Console.Write("程式執行結束!");
BeginInvoke就可以實現非同步操作
BeginInvoke有兩個參數一個是AsyncCallback,一個是object,前一個參數是一個委托,看名字就知道是一個回調函數,當非同步執行完成之後,就會執行回調函數,object代表一個參數,如果回調函數需要參數則通過object傳入。
如果不想通過回調函數,同時又想等待非同步執行完成,那麼可以通過EndInvoke來實現
Action test = () =>
{
int result = 0;
for (int i = 0; i < 1000; i++)
{
result += i;
Thread.Sleep(5);
}
};
test.BeginInvoke((state) =>
{
Console.WriteLine("傳入的參數是"+state.AsyncState);
}, "Test");
以上是帶回調函數的示例
Func<int> test = () =>
{
int r = 0;
for (int i = 0; i < 1000; i++)
{
r += i;
Thread.Sleep(3);
}
return r;
};
var re= test.BeginInvoke(null,null);
int result = test.EndInvoke(re);
以上會為了獲取運行結果的示例