异步伺机拦截UI WP8 [英] async await blocking ui wp8

查看:128
本文介绍了异步伺机拦截UI WP8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知异步等待的关键字就是这样工作的:当一个的await关键字是由编译器遇到的,它暂停异步函数调用程序的执行(在这种情况下,调度员),等待awaitable功能在后台完成,然后再返回到功能。我说得对不对?

As far as I know the async await keywords work this way: when an await keyword is encountered by the compiler, it suspends the execution of the async function to the caller (in this case the dispatcher), waits for the awaitable function to complete in the background and then then returns back to the function. Am I right?

下面是我在做什么:

async private void Button_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
     var p = await query("select* from notes", con);
}   

和这里被调用的函数

 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;
 }

这阻塞UI线程。这究竟是为什么不应该控制调回当它遇到的await关键词调度员?如果是这样,为什么用户界面卡?

This blocks the UI thread. why is this happening shouldn't the control be transferred back to the dispatcher when it encounters the await keyword? If so why does the UI get stuck?

推荐答案

的认识有待大多的正确,它只是不完整的。 等待不立即中止当前方法的执行。首先,该值被期待已久的需求被解析为一个值。一般会有某种方法创建一个工作该任务将创建同步的,然后创建任务之后,当前方法的执行将结束,并继续将被应用到执行的方法的其余部分这一任务。

Your understanding of await is mostly correct, it's just incomplete. await doesn't suspend execution of the current method immediately. First, the value to be awaited needs to be resolved to a value. Typically you'll have some sort of method that creates a Task. That task will be created synchronously, and then after creating that task, execution of the current method will end, and a continuation will be applied to that task that executes the remainder of the method.

对于异步之前的第一个伺机将同步调用者执行方法的一切。它是当第一等待(或方法,或不是由该方法捕获的异常的端部),导致该方法返回的实际任务

For an async method everything before the first await will be performed synchronously by the caller. It is when the first await (or the end of the method, or an exception that isn't caught by the method) that causes the method to return an actual Task.

查询方法的的能够创建工作那些重新presents的操作完成得很快,然后返回,使主叫方可以等待工作。但它没有,它花费5秒创建重新presents何时会完成任务,而当它最终使这项任务的调用者工作已经结束。

Your query method should be able to create the Task that represents the completion of the operation very quickly and then return, so that the caller can await that Task. But it doesn't, it spends over 5 seconds creating the task that represents when it will finish, and when it ends up giving that task to its caller that Task has already finished.

这意味着 Button_Tap 不能屈服的及其的调用者(这是UI的消息循环),直到后查询已完成任务创造了5秒。

This means that Button_Tap can't yield to its caller (which is the UI's message loop) until after query has finished its 5 seconds of task creation.

所有这一切都意味着,对于 Button_Tap 是异步的查询必须是异步的,并且在没有异步它使用了异步关键字,但在这个意义上,该方法几乎立即返回异步调用的时候,那它执行产生控制返回给调用者以后的工作。

All of this means that for Button_Tap to be asynchronous query needs to be asynchronous, and not asynchronous in that it uses the async keyword, but asynchronous in the sense that the method returns almost immediately when called, and that it performs its work after yielding control back to the caller.

至于如何的制作方法异步的,那将依赖。对于IO,如查询数据库,你真正想要的是让查询提供者本身固有的提供异步支持。你想拥有一个返回工作您可以等待,而不是同步返回其结果的查询方法。如果你没有其他选择,那么作为最后的手段,您可以使用 Task.Run 来在非UI线程执行查询,然后等待这一点。

As to how to make the method asynchronous, that'll depend. For IO, such as querying a database, what you really want is to have the query provider itself provide inherently asynchronous support. You want to have a query method that returns a Task that you can await, rather than synchronously returning its results. If you have no other choice, then as a last resort you can use Task.Run to perform the query in a non-UI thread and then await that.

对于 Thread.sleep代码,这也是同步阻塞线程。你需要设定的时间段,而不是之后异步做一些事情(如果你真的需要的延迟)。您可以使用 Task.Delay

As for the Thread.Sleep, that is also synchronously blocking the thread. You need to asynchronously do something after a set period of time instead (if you really do need the delay). You can use Task.Delay for that.

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;
}

在一个侧面说明,你真的不应该试图以这样的重复使用您的数据库连接。它们不是设计为同时使用,对于初学者。实际上他们天生设计用来执行只是一个单一的操作。你应该创建您的连接权当你需要它,并尽快已经执行了一个操作清洗它。

On a side note, you really shouldn't be trying to re-use your database connections like this. They aren't designed to be used concurrently, for starters. Really they're inherently designed to perform just a single operation. You should be creating your connection right when you need it, and cleaning it up as soon as that one operation has been performed.

这篇关于异步伺机拦截UI WP8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆