B0r*_*0de 6 c# multithreading asynchronous windows-phone-8
据我所知async await关键字以这种方式工作:当编译器遇到await关键字时,它会暂停执行异步函数给调用者(在本例中是调度程序),等待等待函数完成后台然后返回到该函数.我对吗?
这就是我在做的事情:
async private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var p = await query("select* from notes", con);
}
Run Code Online (Sandbox Code Playgroud)
这是被调用的函数
async Task<List<notes>> query(string sqlstring, SQLiteConnection con)
{
var p = con.Query<notes>(sqlstring);
Thread.Sleep(5000);
MessageBox.Show(p[0].Data);
return p;
}
Run Code Online (Sandbox Code Playgroud)
这会阻止UI线程.为什么发生这种情况不应该在遇到await关键字时将控制权转移回调度程序?如果是这样,为什么用户界面会被卡住?
Ser*_*rvy 13
你的理解await是多是正确的,它只是不完整的. await不会立即暂停执行当前方法.首先,需要将值等待解析为值.通常你会有某种方法来创建一个Task. 该任务将同步创建,然后在创建该任务后,当前方法的执行将结束,并且将继续执行该任务以执行该方法的其余部分.
对于async方法,第一个之前的所有内容都await将由调用者同步执行.当第一个await(或方法的结尾,或方法没有捕获的异常)导致方法返回实际时Task.
您的query方法应该能够Task非常快速地创建表示操作完成的然后返回,以便调用者能够await这样做Task.但事实并非如此,它花费了超过5秒的时间来创建代表何时完成的任务,以及何时最终将该任务交给Task已完成的调用者.
这意味着在完成5秒的任务创建之后Button_Tap才能屈服于其调用者(这是UI的消息循环)query.
所有这一切都意味着Button_Tap异步query需要是异步的,而不是异步的,因为它使用了async关键字,但是在调用方法几乎立即返回的意义上是异步的,并且它在将控制权交还给控制器之后执行其工作.呼叫者.
至于如何使方法异步,这将取决于.对于IO,例如查询数据库,您真正想要的是让查询提供程序本身提供固有的异步支持.你想拥有一个返回的查询方法Task,你可以await,而不是同步返回其结果.如果您没有其他选择,那么作为最后的手段,您可以使用Task.Run在非UI线程中执行查询然后await.
至于Thread.Sleep,那也是同步阻塞线程.您需要在一段时间后异步执行某些操作(如果您确实需要延迟).你可以用Task.Delay它.
async Task<List<notes>> query(string sqlstring, SQLiteConnection con)
{
var p = await con.QueryAsync<notes>(sqlstring);
//Or, if there is no asynchronous query method
//var p = await Task.Run(() => con.Query<notes>(sqlstring));
await Task.Delay(5000);
MessageBox.Show(p[0].Data);
return p;
}
Run Code Online (Sandbox Code Playgroud)
另外,您真的不应该尝试重复使用这样的数据库连接.对于初学者来说,它们并非旨在同时使用.实际上它们本身就是为了执行一次操作而设计的.您应该在需要时立即创建连接,并在执行一个操作后立即清理它.