2017-03-02 175 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'具有局部效应,不像整行*代码那么大。 –