我对异步作业的执行顺序有疑问。
我会用例子问我的问题,因为它更易于理解。
这是https://msdn.microsoft.com/en-us/library/mt674882.aspx的一个官方例子,但有一些转折。
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
//async operation:
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoWork1();
// The await operator suspends AccessTheWebAsync.
string urlContents = await getStringTask;
DoWork2();
return urlContents.Length;
}
我可以说DoWork2
是client.GetStringAsync
的回调吗?
如果是这样,DoWork2
完成client.GetStringAsync
之后DoWork1
不会立即执行client.GetStringAsync
如果{{1}}的运行时间超过{{1}}。
我在这儿吗?
答案 0 :(得分:5)
完成后,
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN usertable ut ON ut.id = user GROUP BY user'
不会立即执行 如果DoWork2
的运行时间比client.GetStringAsync
长,则为DoWork1
client.GetStringAsync
一旦点击await client.GetStrinkAsync
,DoWork1()
已经完成,从您的示例中看,它的执行是同步的。 client.GetStringAsync
完成后,DoWork2
将设置为执行。
执行流程为:
GetStringAsync
异步启动。它会一直执行,直到它达到它的第一个内部await
,然后将控制权交还给AccessTheWebAsync
。DoWork1()
开始了。因为它是同步的,所以每个人都在等待它的完成client.GetStringAsync
异步等待完成。 await
自然会对其调用者产生执行控制权。client.GetStringAsync
完成后,执行将返回AccessTheWebAsync
,DoWork2()
将同步执行。urlContents.length
将被退回。通常,第一个await
关键字之后的所有内容都设置为该方法其余部分的延续。
答案 1 :(得分:4)
Yuval's answer是正确的。
回答你的后续问题:
有没有办法让client.GetStringAsync完成后立即执行DoWork2?
可能。这取决于此代码的上下文。它不可能同时在UI线程上运行DoWork1
和DoWork2
(显然,单个线程一次只能执行一项操作)。但是如果从线程池上下文中调用它,那么可以同时运行它们。
但是,你应该将你的想法转移到&#34;回调&#34;到&#34;操作&#34;。也就是说,不要将其视为DoWork2
是一个&#34;回调&#34; GetStringAsync
。相反,想一想:我有一个操作GetStringAsync
,我有一个操作DoWork2
;我需要一个新的操作来做一个然后另一个。
一旦你按照这种方式改变思路,解决方案就是为新操作编写一个方法:
async Task<string> GetStringAndDoWork2Async()
{
HttpClient client = new HttpClient();
var result = await client.GetStringAsync("http://msdn.microsoft.com");
DoWork2();
return result;
}
现在,您可以在更高级别的方法中使用该新操作:
async Task<int> AccessTheWebAsync()
{
var task = GetStringAndDoWork2Async();
DoWork1();
string urlContents = await task;
return urlContents.Length;
}
答案 2 :(得分:-1)
在:
//async operation:
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
你正在创建一个运行异步操作的Task,并立即返回给调用者,下一个DoWork1()
同步执行,一旦完成,string urlContents = await getStringTask;
暂停方法的继续,直到等待的任务完成;完成后,程序继续DoWork2()
。