2017-03-02 410 views
0

我試圖理解異步的概念,並等待並不能完全理解它的概念。直到我學到的是Async-await,如果我們調用方法-A,然後使用方法-A等待來調用方法-B,那麼只有在方法B的工作完成後,方法-A的提醒纔會運行。我錯過了什麼嗎?請糾正我。AsyncAwait概念

如果是這樣,則情況每次我們甚至調用方法使用同步編程,該方法-A等待,直到我們已經完成了調用方法-B的提醒時間?

public void methodA(){ 
methodB(); 
Console.Writeline("MethodB has been called"); 
} 
public void methodB(){//do stuff} 

現在用異步等待:

public async Task methodA(){ 
await methodB(); 
Console.Writeline("MethodB has been called"); 
} 
public async Task methodB(){//do stuff} 

請介意我表示有什麼區別?我很難試圖理解這個概念。通常,我在ThreadPool和Threads上看到帖子,但沒有一個清晰的概念,我不太明白。

+0

你做什麼樣的研究?有大量資源試圖解釋異步/等待如何工作。另外,你是否知道Task是什麼,它是如何工作和使用的? – Euphoric

+3

首先,我建議你閱讀[有沒有線程(http://blog.stephencleary.com/2013/11/there-is-no-thread.html)明白,*異步*並不意味着「在另一個線程上運行「。然後認識到'async'和'await'實際上是釋放你當前的線程去實現一些有用的功能,而不是在某種程度上阻塞並等待異步完成。 –

+4

使它看起來一樣完全是async關鍵字的要點。沒有它,你必須編寫兩個方法,一個是methodB去的,另一個是在完成之後運行的。這可能很尷尬,第二種方法不能訪問第一個的任何局部變量。異步/等待它看起來更自然。編譯完成後,實際上最終會有兩種方法。隱藏類的一部分,局部變量現在是該類的字段。所有隱藏的很好,你只能像程序Ildasm.exe反編譯器看到它 –

回答

2

多達我所學到的是異步等待,如果我們調用方法-A,然後使用調用方法-B從法-A,則該方法-A的提醒等待只會方法 - 後運行B的工作已經完成。

你是一種權利。

讓我們來看看其中的異步等待將要使用的實際情況。

比方說,你有一個Windows窗體程序。在窗體上,有一個按鈕。當用戶按下這個按鈕時,程序會從互聯網上獲取一些東西。收到響應後,它會在標籤中顯示響應。

顯然,要求在互聯網上的東西需要一個相當長的時間,比如添加的東西在一起,繪製文本框等操作等

如果不使用異步的await,形式不會當程序正在等待來自服務器的響應時響應用戶交互。這是糟糕的用戶體驗。

現在讓我們使用async-await。我將使用您所提供的代碼:

public async Task methodA(){ 
    await methodB(); 
    Console.Writeline("MethodB has been called"); 
} 
public async Task methodB(){//do stuff} 

methodA按下按鈕時被調用。 methodB提取數據。當達到await行時,methodA立即返回,在methodB被調用後立即返回。這樣,程序執行不需要停留在methodA,因此表單可以響應用戶交互。一個狀態機被創建來記住執行的位置在methodAmethodB返回後,執行回到methodA並執行其餘部分。

+0

因此,基本上,當我們使用的await,我們得到的控制權交還給了methodA(主叫)行後立即等待的methodB運行,但在中了methodA剩餘只有在我們在methodB中的工作完成後才能運行? –

+0

@manisharyal是的,這是正確的。 – Sweeper

+0

1.然後MSDN說只有一個線程? methodB中的工作將在哪裏運行?我在某處等待,讓等待的方法像中斷或卑鄙行爲,但卻無法得到它。 2.在UI/UX應用程序中,當我們等待任何按鈕上的任何行或UI/UX的任何控件時,我們的調用者是uI/ux? –

5

asyncawait是關於讓線程做有用的工作而不是坐等待其他工作來完成。

如果我們編寫的代碼創建一個新的線程來做一些工作,然後立即阻止我們當前的線程等待完成,那太浪費了。爲什麼我們不要只在當前線程上運行代碼,並讓它完成有用的工作,並節省創建新線程的開銷?

那麼,是什麼await辦?它允許我們當前的方法比其所有工作完成時更快地返回到其調用者。也就是說,我們要表明,我們已經得到了我們正在運行的線程沒有電流使用,但希望我們的調用,或我們的來電主叫方,等等,確實有別的它可以被有效地運行我們線。

如果我們的方法有什麼其他的東西可以在當前線程上有用嗎?易 - 解耦創作從await本身awaitable的,和做之間,其他有用的工作:

public async Task methodA(){ 
    var mba = methodB(); 
    Console.Writeline("MethodB has been called"); 
    //Other useful work that doesn't depend on methodB 
    var result = await mba 
    //And now continue with the result from methodB 
} 

如何methodB本身實現其異步完全是一個的methodB實現細節 - 我們所知道的是,它的安排,以完成其在將來某個時間點返回Task(這就是爲什麼其他語言使用諸如「期貨」,或在這裏我們使用「任務」,「承諾」)


對於那些想知道爲什麼這一段存在,它的準確反駁太常見聲稱await「創建一個新線程」或類似。

+0

好的答案,對理解這個概念非常有幫助! – Adil

+0

所以基本上,當我們使用await的時候,我們會在line await methodB運行後立即將控制權返回給methodA(調用者),但是隻有在我們在methodB中的工作完成後,methodA的其餘部分纔會運行? –

+0

@manisharyal - 不,我們將線程返回給調用者*,而'await'正在等待處理。 'await'具有局部效應,不像整行*代碼那麼大。 –