[英]Questions about what runs on the main thread during c#'s async await
我在理解异步等待操作期间在主线程上运行的内容时遇到了麻烦,将不胜感激。
假设我有一个应该用于登录用户的按钮。
它应该在登录过程发生时阻止所有其他用户输入,显示进度视图,然后在显示结果时显示它
这是执行登录的方法
button_clicked(object sender, EventArgs e) {
do_login(); //I do not await the result
do_some_other_stuff(); //this doesn't actually exist I just put it here to ask my questions
}
async Task do_login() {
string user_name = txtUser.Text;
string password = txtPassword.Text;
show_progress(true); //this is not an async method;
string error = await _login.do_login(user_name, password);//this is an async method that can take up to 20 seconds to complete;
show_progress(false);
if (error != null) {
show_error(error);
} else {
show_next_screen();
}
}
关于以上示例,我有两个问题
a)将在主线程上运行什么?
如果我正确理解它,则仅_login.do_login将在单独的线程上运行,其他所有线程都将在主线程上运行,这是否正确?
b)这些方法将以什么顺序执行?
再次,如果我理解正确,它将是:
这个对吗? 如果没有,我如何实现这种行为?
c)如果我上面的代码是正确的,那么为什么我继续收到未等待do_login()的警告? 我不想等待它,我只是希望它运行它可以运行的并在需要时返回,我是否应该忽略该警告?
从技术上讲,取决于do_login
的实现,所有内容都可以在主线程中运行。 在这种情况下,我假设您正在与Web服务器联系,因此不会进行此操作,但这并非总是如此。 并且异步操作不一定在另一个线程中执行。 在以下情况下,一种操作是异步的:
通常,UI线程运行“事件循环”。 因此,异步任务可以简单地将新的工作放入事件队列中,以便在调度程序确定时在同一线程中执行。 在这种情况下,您无需使用两个线程,但是,您不必等待任务完成,也不知道何时完成任务。
确切地说,您帖子中的所有代码都将在主线程中运行。 do_login
中仅管理与服务器的连接,等待和检索数据的部分将异步执行。
您对序列最正确,但需要进行一些调整:
您的主要问题的答案是: 取决于 。 _login.do_login
方法可能会放在其自己的线程上,但实际上取决于.NET任务计划程序。 在WPF和ASP.NET中,如果它不立即返回完成的任务,则将其安排在线程池中。
重要的部分是您知道它不会阻止调用线程(在您的情况下为主线程)的执行。 您对方法流程的理解是正确的,因为您无需等待do_login
。
就警告而言; 您可以将do_login
标记为async void
以避免它,尽管通常只对事件处理程序执行此操作,然后该事件处理程序可以等待Task
返回方法。 如果您确实走了async void
路线; 请确保try/catch
,因为此类方法将一路抛出到根处理程序,并可能导致您的应用崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.