我有这段代码:
private async void Button_Click(object sender, RoutedEventArgs e)
{
Task<int> i = LongTaskAsync(); // first break point here
int k = await i;
print("Done, i=" + i);
}
private async Task<int> LongTaskAsync()
{
await System.Threading.Tasks.Task.Delay(5 * 1000); // second break point here
return 10;
}
调试时,我知道LongTaskAsync正在UI线程上运行。那么,为什么它不阻止UI以及如何阻止?
答案 0 :(得分:1)
来自MSDN
的信息该方法同步运行,直到它到达第一个await表达式,此时方法暂停,直到等待的任务完成。同时,控制返回到方法的调用者
答案 1 :(得分:0)
因为异步/等待构造是异步运行的 - 所以它不会阻止UI。在你的方法“int k = await i;”以异步方式运行。 “使用async修饰符指定方法,lambda表达式或匿名方法是异步的。该方法同步运行,直到它到达第一个await表达式,此时方法将暂停,直到等待的任务完成。同时,控制返回方法的调用者“。这就是为什么你的UI没有被阻止的原因。
答案 2 :(得分:0)
您的功能button_click被声明为异步。调用异步函数不会运行函数内部的代码。相反,代码被调度为由可用线程集合中的一个线程运行任务的请求,该线程称为线程池。
在计划任务之后,异步函数的调用将继续执行下一个语句,直到它到达语句以等待计划任务的结果。
每当线程池中的一个线程空闲时,它将检查是否安排了一段代码,如果是,它将运行代码。如果此线程调用另一个异步函数,则会安排任务等。
大多数异步功能都会在某个地方等待他们安排的任务的结果。因此,每个异步函数应返回任务或任务<TResult
&gt;的规则。而不是虚空或TResult。
唯一的例外是事件处理程序:此方法可以返回async void,表示该任务将被调度,但调用者无法等待它。
此来电者是您的应用程序。应用程序安排一个任务来处理按钮单击事件,但在此事件结束之前不会等待。因此,您的申请将保持响应。
因为您的代码不会等到事件处理程序完成,所以事件程序可以再次调用事件处理程序。这通常会产生不良影响,您应该注意不要发生这种情况,例如通过禁用事件功能入口处的按钮并在事件结束时启用它。
答案 3 :(得分:-1)
当我尝试编写Android代码时,我遇到了同样的问题。后台任务与前台UI任务不同,它们独立运行。
AsyncTasks通常会使用前台中的线程来更新UI并执行与UI相关的任务
例如,
AsyncTask(params)-> {
@Override
protected void onPreExecute() {
super.onPreExecute();
..........
}
@Override
protected String doInBackground(String... params) {
...............
}
@Override
protected void onProgressUpdate(Integer... values) {
...............
}
@Override
protected void onPostExecute(String result) {
.................
}
}
这里,每个任务都可以在自己的UI线程中处理,而不会干扰后台作业,当后台作业完成后,您可以更新UI。同时,您可以使用一些UI动画来保持UI忙碌。
答案 4 :(得分:-1)
您的示例不足以测试异步行为,我使用控制台应用程序测试了该行为。
static void Main(string[] args)
{
string value1 = "First";
Console.WriteLine(value1);
GetSecondFromAsync();
string value3 = "Third";
Console.WriteLine(value3);
string value4 = "Fourth";
Console.WriteLine(value4);
Console.ReadKey();
}
private static async void GetSecondFromAsync()
{
await Task.Delay(3000);
Console.WriteLine("Second");
}
来自MSDN的信息,
该方法同步运行,直到它到达第一个await 表达式,此时该方法暂停,直到等待 任务完成。同时,控制权返回给调用者 方法
在GetSecondFromAsync()中第一次等待时,只有这个方法被挂起,控件返回给调用者并执行剩下的。 所以输出就像
First
Third
Fourth
Second
这意味着Main中的线程未被阻止,它继续...